bean 的自動裝配

HuDu發表於2020-06-22
  • 自動裝配是 Spring 滿足 bean 依賴的一種方式!
  • Spring會在上下文中自動尋找,並自動給bean裝配屬性

在 Spring 中有三種裝配的方式

  • xml 中顯示的配置
  • 在 java 中顯示配置
  • 隱式自動裝配 bean [重要]

測試

建立三個實體類 Cat,Dog,People

public class Cat {
    public void shout(){
        System.out.println("miao~");
    }
}
public class Dog {
  public void shout(){
  System.out.println("wang~");
  }
}
public class People {
    private Cat cat;
    private Dog dog;
    private String name;
}

原先我們配置,是在 xml 中顯示的配置,即上面說的第一種方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="catt" class="com.hudu.pojo.Cat"/>
    <bean id="dogg" class="com.hudu.pojo.Dog"/>

    <bean id="people" class="com.hudu.pojo.People">
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
        <property name="name" value="hudu"/>
    </bean>
</beans>

但是我們的cat和dog使用這兩個實體類,怎麼讓 Spring 自動裝配,,不需要我們手動裝配呢,這裡就說到了上面的第三種方法,我們可以使用 Autowire,有兩種實現方式,一種是byType,另一種是byName,從名字就可以看出他們的區別。

    <!--
    byName:會在容器上下文中查詢,和自己物件set方法後面的值對應的beanid!
    byType:會在容器上下文中查詢,和自己物件屬性型別相同的bean!
    -->
    <bean id="people" class="com.hudu.pojo.People" autowire="byName">
    <!--<bean id="people" class="com.hudu.pojo.People" autowire="byType">-->
        <property name="name" value="hudu"/>
    </bean>

但是兩者都有弊端,對於byName如果bean id配置的名字和 set 方法後面的方法名不一致,無法自動裝配。對於 byType,可以不用配置 bean id,但是如果配置多個物件屬性的相同的 bean,也會無法自動裝配。

小結:

  • byName的時候,需要保證所有的bean的id唯一,並且這個bean需要和自動注入的屬性的set方法的值一直
  • byType的時候,需要保證所有的bean的class唯一,並且需要自動注入的熟屬性的型別一致

使用註解實現自動裝配

上面已經說過一種實現自動裝配的方式,下面是另一種,通過註解實現自動裝配的方式。
jdk1.5支援的註解,Srping從2.5開始支援註解
要使用註解須知:

  • 匯入約束,context約束

  • 配置註解支援,即< context:annotation-config/ >

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!--開啟註解支援-->
    <context:annotation-config/>
    
    <bean id="cat1" class="com.hudu.pojo.Cat"/>
    <bean id="cat111" class="com.hudu.pojo.Cat"/>
    <bean id="dog1" class="com.hudu.pojo.Dog"/>
    <bean id="dog222" class="com.hudu.pojo.Dog"/>
    <bean id="people" class="com.hudu.pojo.People"/>
    </beans>

實體類上的註解

public class People {
    @Autowired
    @Qualifier(value = "cat111")
    //上面兩個效果等於@Resource(value = "cat111")
    private Cat cat;
    @Autowired
    @Qualifier(value = "dog222")
    private Dog dog;
    private String name;
}
如果Autowired不能唯一自動裝配上屬性,則需要通過@Qualifier(value="xxx")

@Nullable   欄位標記了這個註解,說明這個欄位可以為null

和@Autowired類似的是Java原生註解@Resource,會先通過名字去查詢,再通過型別去查詢,可以指定名字@Resource(name = "cat2")

測試類

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        People people = context.getBean("people", People.class);
        people.getDog().shout();
        people.getCat().shout();
  • @Autowired
    直接在屬性上使用即可,也可以在 set 方式上使用
    使用 Autowired 我們可以不用編寫 Set 方法了,前提是你這個自動裝配的屬性在 I0C (Spring) 容器中存在,且符合名字 byname!

小結: @Resource和@ Autowired的區別:

  • 都是用來自動裝配的,都可以放在屬性欄位上
  • @Autowired通過byType的方式實現,而且必須要求這個物件存在! [常用]
  • @Resource預設通過byname的方式實現,如果找不到名字,則通過byType實現!如果兩個都找不到的情況下,就報錯! [常用]
  • 執行順序不同: @Autowired通過byType的方式實現。@ Resource預設通過byname的方式實現。
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章