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

基于@Bean修飾的方法參數(shù)的注入方式

 更新時間:2021年09月22日 10:45:00   作者:文文流云  
這篇文章主要介紹了@Bean修飾的方法參數(shù)的注入方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

@Bean修飾的方法參數(shù)的注入

方法參數(shù)默認注入方式為Autowired,即先根據(jù)類型匹配,若有多個在根據(jù)名稱進行匹配。

1:復雜類型可以通過@Qualifier(value=“XXX”)限定

2:對于普通類型使用@Value(XXX)指定

@PropertySource("classpath:db.properties")
public class SpringConfiguration {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    /**
     * 方法參數(shù)默認注入方式為Autowired: <br>
     * 1:復雜類型可以通過@Qualifier(value="dataSource")限定; <br>
     * 2:對于普通類型使用@Value指定; <br>
     */
    @Bean(name = "dataSource")
    public DataSource dataSource(@Value("${jdbc.driverClass}") String driverClassName,
        @Value("${jdbc.jdbcUrl}") String url, @Value("${jdbc.user}") String username,
        @Value("${jdbc.password}") String password) {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate jdbcTemplate(@Qualifier(value = "dataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

Bean的四種注入方式

我使用下面兩個類來進行注入的演示,這兩個類分別是User和Car類:

Car類:

public class Car {
    // 只包含基本數(shù)據(jù)類型的屬性
    private int speed;
    private double price;
    
    public Car() {
    }
    public Car(int speed, double price) {
        this.speed = speed;
        this.price = price;
    }
    
    public int getSpeed() {
        return speed;
    }
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Car{" +
                "speed=" + speed +
                ", price=" + price +
                '}';
    }
}

User類:

public class User {
	
    private String name;
    private int age;
    // 除了上面兩個基本數(shù)據(jù)類型的屬性,User還依賴Car
    private Car car;
    
    public User() {
    }
    public User(String name, int age, Car car) {
        this.name = name;
        this.age = age;
        this.car = car;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", car=" + car +
                '}';
    }
}

1、set注入

有了上面兩個類,就可以演示set注入了。需要注意一點,如果需要使用set注入,那么必須要為屬性提供set方法,Spring容器就是通過調(diào)用bean的set方法為屬性注入值的。而在xml文件中,使用set注入的方式就是通過property標簽,如下所示:

<!-- 定義car這個bean,id為myCar -->
<bean id="myCar" class="cn.tewuyiang.pojo.Car">
    <!-- 
        為car的屬性注入值,因為speed和price都是基本數(shù)據(jù)類型,所以使用value為屬性設(shè)置值;
        注意,這里的name為speed和price,不是因為屬性名就是speed和price,
        而是set方法分別為setSpeed和setPrice,名稱是通過將set刪除,然后將第一個字母變小寫得出;
    -->
    <property name="speed" value="100"/>
    <property name="price" value="99999.9"/>
</bean>
<!-- 定義user這個bean -->
<bean id="user" class="cn.tewuyiang.pojo.User">
    <property name="name" value="aaa" />
    <property name="age" value="123" />
    <!-- car是引用類型,所以這里使用ref為其注入值,注入的就是上面定義的myCar 
         基本數(shù)據(jù)類型或Java包裝類型使用value,
         而引用類型使用ref,引用另外一個bean的id 
    -->
    <property name="car" ref="myCar" />
</bean>

通過上面的配置,就可以為Car和User這兩個類型的bean注入值了。需要注意的是,property的name屬性,填寫的不是屬性的名稱,而是set方法去除set,然后將第一個字符小寫后的結(jié)果。對于基本數(shù)據(jù)類型,或者是Java的包裝類型(比如String),使用value注入值,而對于引用類型,則使用ref,傳入其他bean的id。接下來就可以測試效果了:

@Test
public void test1() {
    ApplicationContext context =
        new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    // 獲取user這個bean
    User user = context.getBean(User.class);
    // 輸出產(chǎn)看結(jié)果
    System.out.println(user);
}

由于user包含car的引用,所以直接輸出user,也能夠看到car的情況,輸入結(jié)果如下:

User{name='aaa', age=123, car=Car{speed=100, price=99999.9}}

2、構(gòu)造器注入

下面來說第二種方式——構(gòu)造器注入。聽名字就可以知道,這種注入值的方式,就是通過調(diào)用bean所屬類的帶參構(gòu)造器為bean的屬性注入值。這也就意味著,如果需要使用構(gòu)造器注入,就得為類提供包含參數(shù)的構(gòu)造方法。構(gòu)造器注入,實際上有多種匹配屬性值的方式,下面就來一一列舉。這里依然使用定義的Car和User這兩個類,測試方法以及類的定義都不需要變,需要改變的僅僅是xml配置文件。

(一)匹配構(gòu)造器的參數(shù)名稱

需要通過constructor-arg標簽為構(gòu)造器傳入?yún)?shù)值,但是每個constructor-arg標簽對應(yīng)哪一個參數(shù)值呢?這就有多種方式指定了。第一種就是直接匹配參數(shù)名,配置如下:

<bean id="myCar" class="cn.tewuyiang.pojo.Car">
    <!-- 通過constructor-arg的name屬性,指定構(gòu)造器參數(shù)的名稱,為參數(shù)賦值 -->
    <constructor-arg name="speed" value="100" />
    <constructor-arg name="price" value="99999.9"/>
</bean>
<bean id="user" class="cn.tewuyiang.pojo.User">
    <constructor-arg name="name" value="aaa" />
    <constructor-arg name="age" value="123" />
    <!-- 
         和之前一樣,基本數(shù)據(jù)類型或Java包裝類型使用value,
         而引用類型使用ref,引用另外一個bean的id 
    -->
    <constructor-arg name="car" ref="myCar" />
</bean>

這樣就完成了,測試代碼和之前一樣,運行結(jié)果也一樣,這里的配置和set注入時的配置幾乎一樣,除了一個使用property,一個使用constructor-arg。寫法上一樣,但是表示的含義卻完全不同。property的name屬性,是通過set方法的名稱得來;而constructor-arg的name,則是構(gòu)造器參數(shù)的名稱。

(二)匹配構(gòu)造器的參數(shù)下標

上面是通過構(gòu)造器參數(shù)的名稱,匹配需要傳入的值,那種方式最為直觀,而Spring還提供另外兩種方式匹配參數(shù),這里就來說說通過參數(shù)在參數(shù)列表中的下標進行匹配的方式。下面的配置,請結(jié)合User和Car的構(gòu)造方法一起閱讀,配置方式如下:

<bean id="car" class="cn.tewuyiang.pojo.Car">
    <!-- 下標編號從0開始,構(gòu)造器的第一個參數(shù)是speed,為它賦值100 -->
    <constructor-arg index="0" value="100" />
    <!-- 構(gòu)造器的第二個參數(shù)是price,為它賦值99999.9 -->
    <constructor-arg index="1" value="99999.9"/>
</bean>
<bean id="user" class="cn.tewuyiang.pojo.User">
    <!-- 與上面car的配置同理 -->
    <constructor-arg index="0" value="aaa" />
    <constructor-arg index="1" value="123" />
    <constructor-arg index="2" ref="car" />
</bean>

上面就是通過參數(shù)的下標為構(gòu)造器的參數(shù)賦值,需要注意的是,參實的下標從0開始。使用上面的方式配置,若賦值的類型與參數(shù)的類型不一致,將會在容器初始化bean的時候拋出異常。如果bean存在多個參數(shù)數(shù)量一樣的構(gòu)造器,Spring容器會自動找到類型匹配的那個進行調(diào)用。比如說,Car有如下兩個構(gòu)造器,Spring容器將會調(diào)用第二個,因為上面的配置中,index = 1對應(yīng)的value是double類型,與第二個構(gòu)造器匹配,而第一個不匹配:

public Car(double price, int speed) {
    this.speed = speed;
    this.price = price;
}
// 將使用匹配這個構(gòu)造器
public Car(int speed, double price) {
    this.speed = speed;
    this.price = price;
}

還存在另外一種特殊情況,那就是多個構(gòu)造器都滿足bean的配置,此時選擇哪一個?假設(shè)當前car的配置是這樣的:

<bean id="car" class="cn.tewuyiang.pojo.Car">
    <!-- 兩個下標的value值都是整數(shù) -->
    <constructor-arg index="0" value="100" />
    <constructor-arg index="1" value="999"/>
</bean>

假設(shè)Car還是有上面兩個構(gòu)造器,兩個構(gòu)造器都是一個int類型一個double類型的參數(shù),只是位置不同。而配置中,指定的兩個值都是int類型。但是,int類型也可以使用double類型存儲,所以上面兩個構(gòu)造器都是匹配的,此時調(diào)用哪一個呢?結(jié)論就是調(diào)用第二個。自己去嘗試就會發(fā)現(xiàn),若存在多個構(gòu)造器匹配bean的定義,Spring容器總是使用最后一個滿足條件的構(gòu)造器。

(三)匹配構(gòu)造器的參數(shù)類型

下面說最后一種匹配方式——匹配構(gòu)造器的參數(shù)類型。直接看配置文件吧:

<bean id="car" class="cn.tewuyiang.pojo.Car">
    <!-- 使用type屬性匹配類型,car的構(gòu)造器包含兩個參數(shù),一個是int類型,一個是double類型 -->
    <constructor-arg type="int" value="100" />
    <constructor-arg type="double" value="99999.9"/>
</bean>
<bean id="user" class="cn.tewuyiang.pojo.User">
    <!-- 對于引用類型,需要使用限定類名 -->
    <constructor-arg type="java.lang.String" value="aaa" />
    <constructor-arg type="int" value="123" />
    <constructor-arg type="cn.tewuyiang.pojo.Car" ref="car" />
</bean>

上面應(yīng)該不難理解,直接通過匹配構(gòu)造器的參數(shù)類型,從而選擇一個能夠完全匹配的構(gòu)造器,調(diào)用這個構(gòu)造器完成bean的創(chuàng)建和屬性注入。需要注意的是,上面的配置中,類型并不需要按構(gòu)造器中聲明的順序編寫,Spring也能進行匹配。這也就意味著可能出現(xiàn)多個能夠匹配的構(gòu)造器,和上一個例子中一樣。比如說,Car還是有下面兩個構(gòu)造器:

public Car(double price, int speed) {
    // 輸出一句話,看是否調(diào)用這個構(gòu)造器
    System.out.println(111);
    this.speed = speed;
    this.price = price;
}
// 將使用匹配這個構(gòu)造器
public Car(int speed, double price) {
    // 輸出一句話,看是否調(diào)用這個構(gòu)造器
    System.out.println(222);
    this.speed = speed;
    this.price = price;
}

上面兩個構(gòu)造器都是一個int,一個double類型的參數(shù),都符合xml文件中,car這個bean的配置。通過測試發(fā)現(xiàn),Spring容器使用的永遠都是最后一個符合條件的構(gòu)造器,這和上面通過下標匹配是一致的。需要說明的一點是,這三種使用構(gòu)造器注入的方式,可以混用。

3、靜態(tài)工廠注入

靜態(tài)工廠注入就是編寫一個靜態(tài)的工廠方法,這個工廠方法會返回一個需要的值,然后在配置文件中,指定使用這個工廠方法創(chuàng)建bean。首先需要一個靜態(tài)工廠,如下所示:

public class SimpleFactory {
    /**
     * 靜態(tài)工廠,返回一個Car的實例對象
     */
    public static Car getCar() {
        return new Car(12345, 5.4321);
    }
}

下面需要在xml中配置car這個bean,并指定它由工廠方法進行創(chuàng)建。配置如下:

<!-- 
 注意,這里的配置并不是創(chuàng)建一個SimpleFactory對象,取名為myCar,
    這一句配置的意思是,調(diào)用SimpleFactory的getCar方法,創(chuàng)建一個car實例對象,
    將這個car對象取名為myCar。
-->
<bean id="car" class="cn.tewuyiang.factory.SimpleFactory" factory-method="getCar"/>
<bean id="user" class="cn.tewuyiang.pojo.User">
    <!-- name和age使用set注入 -->
    <property name="name" value="aaa"/>
    <property name="age" value="123"/>
    <!-- 將上面配置的car,注入到user的car屬性中 -->
    <property name="car" ref="car"/>
</bean>

以上就配置成功了,測試方法以及執(zhí)行效果如下,注意看car的屬性值,就是在靜態(tài)工廠中配置的那樣,這說明,Spring容器確實是使用定義的靜態(tài)工廠方法,創(chuàng)建了car這個bean:

@Test
public void test1() {
    ApplicationContext context =
        new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    // 獲取靜態(tài)工廠創(chuàng)建的car
    Car car = (Car) context.getBean("car");
    // 獲取user
    User user = context.getBean(User.class);
    System.out.println(car);
    System.out.println(user);
}

輸出如下所示:

Car{speed=12345, price=5.4321}

User{name='aaa', age=123, car=Car{speed=12345, price=5.4321}}

4、實例工廠注入

實例工廠與靜態(tài)工廠類似,不同的是,靜態(tài)工廠調(diào)用工廠方法不需要先創(chuàng)建工廠類的對象,因為靜態(tài)方法可以直接通過類調(diào)用,所以在上面的配置文件中,并沒有聲明工廠類的bean。但是,實例工廠,需要有一個實例對象,才能調(diào)用它的工廠方法。先看看實例工廠的定義:

public class SimpleFactory {
    /**
     * 實例工廠方法,返回一個Car的實例對象
     */
    public Car getCar() {
        return new Car(12345, 5.4321);
    }
    /**
     * 實例工廠方法,返回一個String
     */
    public String getName() {
        return "tewuyiang";
    }
    /**
     * 實例工廠方法,返回一個int,在Spring容器中會被包裝成Integer
     */
    public int getAge() {
        return 128;
    }
}

在上面的工廠類中,共定義了三個工廠方法,分別用來返回user所需的car,name以及age,而配置文件如下:

<!-- 聲明實例工廠bean,Spring容器需要先創(chuàng)建一個SimpleFactory對象,才能調(diào)用工廠方法 -->
<bean id="factory" class="cn.tewuyiang.factory.SimpleFactory" />
<!-- 
    通過實例工廠的工廠方法,創(chuàng)建三個bean,通過factory-bean指定工廠對象,
    通過factory-method指定需要調(diào)用的工廠方法
-->
<bean id="name" factory-bean="factory" factory-method="getName" />
<bean id="age" factory-bean="factory" factory-method="getAge" />
<bean id="car" factory-bean="factory" factory-method="getCar" />
<bean id="user" class="cn.tewuyiang.pojo.User">
    <!-- 將上面通過實例工廠方法創(chuàng)建的bean,注入到user中 -->
    <property name="name" ref="name"/>
    <property name="age" ref="age"/>
    <property name="car" ref="car"/>
</bean>

嘗試從Spring容器中取出name,age,car以及user,看看它們的值,測試代碼如下:

@Test
public void test1() {
    ApplicationContext context =
        new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    // 獲取靜態(tài)工廠創(chuàng)建的car,name和age這三個bean
    Car car = (Car) context.getBean("car");
    String name = (String) context.getBean("name");
    Integer age = (Integer) context.getBean("age");
    // 獲取user這個bean
    User user = context.getBean(User.class);
    System.out.println(car);
    System.out.println(name);
    System.out.println(age);
    System.out.println(user);
}

以下就是輸出結(jié)果,可以看到,通過工廠創(chuàng)建的bean,都在Spring容器中能夠獲取到:

Car{speed=12345, price=5.4321}

tewuyiang

128

User{name='tewuyiang', age=128, car=Car{speed=12345, price=5.4321}}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • idea如何通過maven指定JDK版本

    idea如何通過maven指定JDK版本

    這篇文章主要介紹了idea如何通過maven指定JDK版本問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot讀取自定義配置文件方式(properties,yaml)

    SpringBoot讀取自定義配置文件方式(properties,yaml)

    這篇文章主要介紹了SpringBoot讀取自定義配置文件方式(properties,yaml),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Netty分布式ByteBuf使用的底層實現(xiàn)方式源碼解析

    Netty分布式ByteBuf使用的底層實現(xiàn)方式源碼解析

    這篇文章主要為大家介紹了Netty分布式ByteBuf使用底層實現(xiàn)方式源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • Spring框架學習之Cache抽象詳解

    Spring框架學習之Cache抽象詳解

    這篇文章主要為大家介紹了Spring框架學習中Cache抽象詳解示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-10-10
  • JavaMail整合Spring實現(xiàn)郵件發(fā)送功能

    JavaMail整合Spring實現(xiàn)郵件發(fā)送功能

    這篇文章主要為大家詳細介紹了JavaMail整合Spring實現(xiàn)郵件發(fā)送功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • java使用TimerTask定時器獲取指定網(wǎng)絡(luò)數(shù)據(jù)

    java使用TimerTask定時器獲取指定網(wǎng)絡(luò)數(shù)據(jù)

    java.util.Timer定時器,實際上是個線程,定時調(diào)度所擁有的TimerTasks。一個TimerTask實際上就是一個擁有run方法的類,需要定時執(zhí)行的代碼放到run方法體內(nèi),TimerTask一般是以匿名類的方式創(chuàng)建,下面的就用示例來學習他的使用方法
    2014-01-01
  • 一文帶你了解Spring中@Enable開頭注解的使用

    一文帶你了解Spring中@Enable開頭注解的使用

    前面的文章給大家介紹?Spring?的重試機制的時候有提到過?Spring?有很多?@Enable?開頭的注解,平時在使用的時候也沒有注意過為什么會有這些注解,今天就給大家介紹一下
    2022-09-09
  • 關(guān)于java關(guān)鍵字this和super的區(qū)別和理解

    關(guān)于java關(guān)鍵字this和super的區(qū)別和理解

    這篇文章主要給大家介紹了關(guān)于java關(guān)鍵字this和super的區(qū)別和理解的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • 使用Java如何對復雜的數(shù)據(jù)類型排序和比大小

    使用Java如何對復雜的數(shù)據(jù)類型排序和比大小

    我相信大家在第一次接觸算法的時候,最先接觸的肯定也是從排序算法開始的,下面這篇文章主要給大家介紹了關(guān)于使用Java如何對復雜的數(shù)據(jù)類型排序和比大小的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • Java 設(shè)計模式以虹貓藍兔的故事講解建造者模式

    Java 設(shè)計模式以虹貓藍兔的故事講解建造者模式

    建造者模式,是一種對象構(gòu)建模式 它可以將復雜對象的建造過程抽象出來,使這個抽象過程的不同實現(xiàn)方法可以構(gòu)造出不同表現(xiàn)的對象。本文將通過示例講解建造者模式,需要的可以參考一下
    2022-04-04

最新評論