最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

@PropertySource("classpath:db.properties")
public class SpringConfiguration {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    /**
     * 方法參數(shù)默認(rèn)注入方式為Autowired: <br>
     * 1:復(fù)雜類型可以通過@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的四種注入方式

我使用下面兩個(gè)類來進(jìn)行注入的演示,這兩個(gè)類分別是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;
    // 除了上面兩個(gè)基本數(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注入

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

<!-- 定義car這個(gè)bean,id為myCar -->
<bean id="myCar" class="cn.tewuyiang.pojo.Car">
    <!-- 
        為car的屬性注入值,因?yàn)閟peed和price都是基本數(shù)據(jù)類型,所以使用value為屬性設(shè)置值;
        注意,這里的name為speed和price,不是因?yàn)閷傩悦褪莝peed和price,
        而是set方法分別為setSpeed和setPrice,名稱是通過將set刪除,然后將第一個(gè)字母變小寫得出;
    -->
    <property name="speed" value="100"/>
    <property name="price" value="99999.9"/>
</bean>
<!-- 定義user這個(gè)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,引用另外一個(gè)bean的id 
    -->
    <property name="car" ref="myCar" />
</bean>

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

@Test
public void test1() {
    ApplicationContext context =
        new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    // 獲取user這個(gè)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)造器注入,實(shí)際上有多種匹配屬性值的方式,下面就來一一列舉。這里依然使用定義的Car和User這兩個(gè)類,測試方法以及類的定義都不需要變,需要改變的僅僅是xml配置文件。

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

需要通過constructor-arg標(biāo)簽為構(gòu)造器傳入?yún)?shù)值,但是每個(gè)constructor-arg標(biāo)簽對應(yīng)哪一個(gè)參數(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,引用另外一個(gè)bean的id 
    -->
    <constructor-arg name="car" ref="myCar" />
</bean>

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

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

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

<bean id="car" class="cn.tewuyiang.pojo.Car">
    <!-- 下標(biāo)編號(hào)從0開始,構(gòu)造器的第一個(gè)參數(shù)是speed,為它賦值100 -->
    <constructor-arg index="0" value="100" />
    <!-- 構(gòu)造器的第二個(gè)參數(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ù)的下標(biāo)為構(gòu)造器的參數(shù)賦值,需要注意的是,參實(shí)的下標(biāo)從0開始。使用上面的方式配置,若賦值的類型與參數(shù)的類型不一致,將會(huì)在容器初始化bean的時(shí)候拋出異常。如果bean存在多個(gè)參數(shù)數(shù)量一樣的構(gòu)造器,Spring容器會(huì)自動(dòng)找到類型匹配的那個(gè)進(jìn)行調(diào)用。比如說,Car有如下兩個(gè)構(gòu)造器,Spring容器將會(huì)調(diào)用第二個(gè),因?yàn)樯厦娴呐渲弥?,index = 1對應(yīng)的value是double類型,與第二個(gè)構(gòu)造器匹配,而第一個(gè)不匹配:

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

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

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

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

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

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

<bean id="car" class="cn.tewuyiang.pojo.Car">
    <!-- 使用type屬性匹配類型,car的構(gòu)造器包含兩個(gè)參數(shù),一個(gè)是int類型,一個(gè)是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è)能夠完全匹配的構(gòu)造器,調(diào)用這個(gè)構(gòu)造器完成bean的創(chuàng)建和屬性注入。需要注意的是,上面的配置中,類型并不需要按構(gòu)造器中聲明的順序編寫,Spring也能進(jìn)行匹配。這也就意味著可能出現(xiàn)多個(gè)能夠匹配的構(gòu)造器,和上一個(gè)例子中一樣。比如說,Car還是有下面兩個(gè)構(gòu)造器:

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

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

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

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

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

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

<!-- 
 注意,這里的配置并不是創(chuàng)建一個(gè)SimpleFactory對象,取名為myCar,
    這一句配置的意思是,調(diào)用SimpleFactory的getCar方法,創(chuàng)建一個(gè)car實(shí)例對象,
    將這個(gè)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容器確實(shí)是使用定義的靜態(tài)工廠方法,創(chuàng)建了car這個(gè)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、實(shí)例工廠注入

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

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

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

<!-- 聲明實(shí)例工廠bean,Spring容器需要先創(chuàng)建一個(gè)SimpleFactory對象,才能調(diào)用工廠方法 -->
<bean id="factory" class="cn.tewuyiang.factory.SimpleFactory" />
<!-- 
    通過實(shí)例工廠的工廠方法,創(chuàng)建三個(gè)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">
    <!-- 將上面通過實(shí)例工廠方法創(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這三個(gè)bean
    Car car = (Car) context.getBean("car");
    String name = (String) context.getBean("name");
    Integer age = (Integer) context.getBean("age");
    // 獲取user這個(gè)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}}

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

相關(guān)文章

  • java 使用JDBC構(gòu)建簡單的數(shù)據(jù)訪問層實(shí)例詳解

    java 使用JDBC構(gòu)建簡單的數(shù)據(jù)訪問層實(shí)例詳解

    以下是如何使用JDBC構(gòu)建一個(gè)數(shù)據(jù)訪問層,包括數(shù)據(jù)轉(zhuǎn)換(將從數(shù)據(jù)庫中查詢的數(shù)據(jù)封裝到對應(yīng)的對象中……),數(shù)據(jù)庫的建立,以及如何連接到數(shù)據(jù)庫,需要的朋友可以參考下
    2016-11-11
  • Java獲取月份的三種方法總結(jié)

    Java獲取月份的三種方法總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java獲取月份的三種方法,文中分別介紹了使用java.util.Date、java.util.Calendar和java.time包中的LocalDate類,推薦使用java.time包中的LocalDate,因?yàn)樗峁┝烁鼮楹啙嵑蛷?qiáng)大的功能,需要的朋友可以參考下
    2024-12-12
  • MyBatis 如何簡化的 JDBC(思路詳解)

    MyBatis 如何簡化的 JDBC(思路詳解)

    MyBatis 是一個(gè) 持久層 框架,用于 簡化JDBC開發(fā),這篇文章主要介紹了MyBatis 如何簡化的 JDBC(思路詳解),需要的朋友可以參考下
    2023-03-03
  • Java的Atomic原子類詳解

    Java的Atomic原子類詳解

    這篇文章主要介紹了Java的Atomic原子類詳解,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 過濾器 和 攔截器的 6個(gè)區(qū)別(別再傻傻分不清了)

    過濾器 和 攔截器的 6個(gè)區(qū)別(別再傻傻分不清了)

    這篇文章主要介紹了過濾器 和 攔截器的 6個(gè)區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • java實(shí)現(xiàn)會(huì)反彈的小球示例

    java實(shí)現(xiàn)會(huì)反彈的小球示例

    這篇文章主要介紹了java實(shí)現(xiàn)會(huì)反彈的小球示例,需要的朋友可以參考下
    2014-04-04
  • @JsonDeserialize和@JsonSerialize注解的使用方式

    @JsonDeserialize和@JsonSerialize注解的使用方式

    這篇文章主要介紹了@JsonDeserialize和@JsonSerialize注解的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 基于Javamail實(shí)現(xiàn)發(fā)送郵件(QQ/網(wǎng)易郵件服務(wù)器)

    基于Javamail實(shí)現(xiàn)發(fā)送郵件(QQ/網(wǎng)易郵件服務(wù)器)

    這篇文章主要介紹了基于Javamail實(shí)現(xiàn)發(fā)送郵件,分別使用QQ郵箱作為smtp郵件服務(wù)器發(fā)送郵件,使用網(wǎng)易郵箱作為smtp郵件服務(wù)器發(fā)送郵件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • JAVA實(shí)現(xiàn)二維碼生成加背景圖代碼實(shí)例

    JAVA實(shí)現(xiàn)二維碼生成加背景圖代碼實(shí)例

    這篇文章主要介紹了JAVA實(shí)現(xiàn)二維碼生成加背景圖代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Spring中BeanUtils.copyProperties的坑及解決

    Spring中BeanUtils.copyProperties的坑及解決

    這篇文章主要介紹了Spring中BeanUtils.copyProperties的坑及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09

最新評論

道真| 阳春市| 栾城县| 泸西县| 那坡县| 合江县| 甘谷县| 龙井市| 江北区| 辉县市| 四会市| 肥东县| 乌拉特中旗| 和林格尔县| 鸡泽县| 玛纳斯县| 昌宁县| 忻城县| 钟祥市| 彩票| 嘉义市| 宜春市| 河东区| 天门市| 吉林省| 临沧市| 那坡县| 南部县| 社会| 衡山县| 类乌齐县| 侯马市| 武义县| 抚州市| 东阳市| 大荔县| 淮安市| 靖宇县| 辽中县| 陵川县| 伊吾县|