欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring 中使用反射創(chuàng)建 Bean 實例的幾種方式

 更新時間:2025年03月21日 11:00:18   作者:冰糖心書房  
文章介紹了在Spring框架中如何使用反射來創(chuàng)建Bean實例,包括使用Class.newInstance()、Constructor.newInstance()、工廠方法以及Spring的BeanUtils工具類,文章還強調(diào)了反射操作的注意事項,如異常處理、性能、安全性以及類型安全,感興趣的朋友一起看看吧

在 Spring 中,雖然框架內(nèi)部大量使用了反射來創(chuàng)建 Bean 實例,但通常情況下,我們不需要直接使用反射來創(chuàng)建 Bean。Spring 容器會根據(jù) Bean 定義自動完成 Bean 的創(chuàng)建和管理。

不過,了解如何使用反射創(chuàng)建 Bean 實例有助于我們更深入地理解 Spring 的工作原理,以及在某些特殊情況下(例如,自定義 FactoryBean、編寫測試代碼、動態(tài)創(chuàng)建對象等)進行更靈活的操作。

以下是使用反射創(chuàng)建 Bean 實例的幾種方式:

1. 使用 Class.newInstance() (僅限無參構(gòu)造函數(shù)):

這是最簡單的方式,但只能用于具有 public 無參構(gòu)造函數(shù) 的類。已過時 (Deprecated): 從 Java 9 開始,Class.newInstance() 方法已被標記為過時,推薦使用 getDeclaredConstructor().newInstance()。

public class MyBean {
    public MyBean() {
        System.out.println("MyBean created using default constructor.");
    }
}
public class CreateBeanWithReflection {
    public static void main(String[] args) throws Exception {
        // 使用 Class.newInstance() (已過時)
        Class<MyBean> clazz = MyBean.class;
        MyBean myBean = clazz.newInstance(); // 創(chuàng)建 MyBean 實例
    }
}

2. 使用 Constructor.newInstance() (推薦):

  • 這是更靈活的方式,可以用于具有任何類型構(gòu)造函數(shù)(包括私有構(gòu)造函數(shù)、帶參數(shù)的構(gòu)造函數(shù))的類。
  • 需要先獲取 Constructor 對象,然后調(diào)用其 newInstance() 方法。
import java.lang.reflect.Constructor;
public class MyBean {
    private String name;
    private int age;
    // 無參構(gòu)造函數(shù)
    public MyBean() {
        System.out.println("MyBean created using default constructor.");
    }
    // 帶參數(shù)的構(gòu)造函數(shù)
    public MyBean(String name, int age) {
        System.out.println("MyBean created using parameterized constructor.");
        this.name = name;
        this.age = age;
    }
    // 私有構(gòu)造函數(shù)
    private MyBean(String name){
        System.out.println("MyBean created using private constructor");
        this.name = name;
    }
}
 public class CreateBeanWithReflection {
    public static void main(String[] args) throws Exception {
         Class<MyBean> clazz = MyBean.class;
        // 1. 使用無參構(gòu)造函數(shù)
        Constructor<MyBean> defaultConstructor = clazz.getDeclaredConstructor();
        MyBean myBean1 = defaultConstructor.newInstance();
        // 2. 使用帶參數(shù)的構(gòu)造函數(shù)
        Constructor<MyBean> parameterizedConstructor = clazz.getDeclaredConstructor(String.class, int.class);
        MyBean myBean2 = parameterizedConstructor.newInstance("John", 30);
        // 3. 使用私有構(gòu)造函數(shù)
        Constructor<MyBean> privateConstructor = clazz.getDeclaredConstructor(String.class);
        privateConstructor.setAccessible(true); // 設(shè)置可訪問私有構(gòu)造函數(shù)
        MyBean myBean3 = privateConstructor.newInstance("Private Bean");
    }
}

3. 使用工廠方法 (Factory Method):

  • 如果 Bean 是通過工廠方法創(chuàng)建的,可以使用反射調(diào)用工廠方法。
  • 靜態(tài)工廠方法:
    • 獲取工廠類的 Class 對象。
    • 獲取工廠方法的 Method 對象。
    • 調(diào)用 Method.invoke(null, ...),第一個參數(shù)為 null,表示調(diào)用靜態(tài)方法。
  • 實例工廠方法:
    • 創(chuàng)建工廠類的實例。
    • 獲取工廠方法的 Method 對象。
    • 調(diào)用 Method.invoke(factoryInstance, ...),第一個參數(shù)為工廠類的實例。
import java.lang.reflect.Method;
public class MyBean {
    private String message;
    private MyBean(String message) {
        this.message = message;
    }
    // 靜態(tài)工廠方法
    public static MyBean createInstance(String message) {
        return new MyBean(message);
    }
    public String getMessage(){
        return  message;
    }
}
//工廠類
public class MyBeanFactory{
     public MyBean createMyBean(String message){
         return  new MyBean(message);
     }
}
public class CreateBeanWithReflection {
    public static void main(String[] args) throws Exception {
        // 1. 使用靜態(tài)工廠方法
        Class<MyBean> clazz = MyBean.class;
        Method staticFactoryMethod = clazz.getDeclaredMethod("createInstance", String.class);
        MyBean myBean1 = (MyBean) staticFactoryMethod.invoke(null, "Hello from static factory method");
         System.out.println(myBean1.getMessage());
        // 2. 使用實例工廠方法
        MyBeanFactory factory = new MyBeanFactory(); // 創(chuàng)建工廠實例
        Method instanceFactoryMethod = MyBeanFactory.class.getDeclaredMethod("createMyBean", String.class);
        MyBean myBean2 = (MyBean) instanceFactoryMethod.invoke(factory, "Hello from instance factory method");
        System.out.println(myBean2.getMessage());
    }
}

4. 使用 BeanUtils (Spring Framework):

  • Spring 的 BeanUtils 類提供了一些便捷的方法來創(chuàng)建 Bean 實例和操作 Bean 屬性。
  • BeanUtils.instantiateClass()
import org.springframework.beans.BeanUtils;
public class MyBean {
    public MyBean() {
        System.out.println("MyBean created using default constructor.");
    }
}
public class CreateBeanWithReflection {
    public static void main(String[] args) throws Exception {
        // 使用 BeanUtils.instantiateClass()
        MyBean myBean = BeanUtils.instantiateClass(MyBean.class);
    }
}

注意事項:

  • 異常處理: 反射操作可能會拋出各種異常(NoSuchMethodException、IllegalAccessException、InstantiationExceptionInvocationTargetException 等),需要進行適當?shù)漠惓L幚怼?/li>
  • 性能: 反射操作通常比直接調(diào)用構(gòu)造函數(shù)或方法要慢一些。如果性能非常關(guān)鍵,應(yīng)盡量避免不必要的反射。
  • 安全性: 如果需要訪問私有構(gòu)造函數(shù)或方法,需要使用 setAccessible(true),但這會破壞封裝性,應(yīng)謹慎使用。
  • 類型安全: 反射操作是運行時進行的,可能會導致類型安全問題。

到此這篇關(guān)于Spring 中如何使用反射創(chuàng)建 Bean 實例?的文章就介紹到這了,更多相關(guān)Spring 使用反射創(chuàng)建 Bean 實例內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Json字符串與Object、List、Map的互轉(zhuǎn)工具類

    Json字符串與Object、List、Map的互轉(zhuǎn)工具類

    今天小編就為大家分享一篇關(guān)于Json字符串與Object、List、Map的互轉(zhuǎn)工具類,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • SpringBoot超詳細講解yaml配置文件

    SpringBoot超詳細講解yaml配置文件

    這篇文章主要介紹了SpringBoot中的yaml配置文件問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • Java使用openOffice對于word的轉(zhuǎn)換及遇到的問題解決

    Java使用openOffice對于word的轉(zhuǎn)換及遇到的問題解決

    開發(fā)過程中經(jīng)常會使用java將office系列文檔轉(zhuǎn)換為PDF, 一般都使用微軟提供的openoffice+jodconverter 實現(xiàn)轉(zhuǎn)換文檔,下面這篇文章主要給大家介紹了關(guān)于Java通過openOffice對于word的轉(zhuǎn)換及遇到問題的解決方法,需要的朋友可以參考下
    2018-09-09
  • Java表格JTable代碼實例解析

    Java表格JTable代碼實例解析

    這篇文章主要介紹了Java表格JTable代碼實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Spring Data Jpa如何實現(xiàn)批量插入或更新

    Spring Data Jpa如何實現(xiàn)批量插入或更新

    文章總結(jié):本文分享了四種Spring Data JPA批量插入或更新的方法,包括BatchConsumer、QueryParameterBuilder、KeyValue和SqlUtil,旨在為開發(fā)者提供實用的參考
    2024-12-12
  • 基于web項目log日志指定輸出文件位置配置方法

    基于web項目log日志指定輸出文件位置配置方法

    下面小編就為大家分享一篇基于web項目log日志指定輸出文件位置配置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Java中的Unsafe工具類使用詳解

    Java中的Unsafe工具類使用詳解

    這篇文章主要介紹了Java中的Unsafe工具類使用詳解,Unsafe是jdk提供的一個直接訪問操作系統(tǒng)資源的工具類(底層c++實現(xiàn)),它可以直接分配內(nèi)存,內(nèi)存復制,copy,提供cpu級別的CAS樂觀鎖等操作,需要的朋友可以參考下
    2023-12-12
  • Mybatis框架之代理模式(Proxy Pattern)的實現(xiàn)

    Mybatis框架之代理模式(Proxy Pattern)的實現(xiàn)

    本文主要介紹了MyBatis框架中使用代理模式ProxyPattern的原理和實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-11-11
  • Mybatis?plus多租戶方案的實戰(zhàn)踩坑記錄

    Mybatis?plus多租戶方案的實戰(zhàn)踩坑記錄

    MybaitsPlus多租戶處理器是一個對于多租戶問題的解決方案,下面這篇文章主要給大家介紹了關(guān)于Mybatis?plus多租戶方案踩坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-12-12
  • Java BigDecimal中divide方法案例詳解

    Java BigDecimal中divide方法案例詳解

    這篇文章主要介紹了Java BigDecimal中divide方法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評論