天天看點

Spring自動裝配Spring的四種自動裝配模式:No、byName、byType、constructor@Resource

Spring的四種自動裝配模式:No、byName、byType、constructor

自動轉配就是類中的定義的其他的引用導緻類與類中有了依賴關系,需要管理他們的依賴關系,Spring可以使用自動裝配的方式,自動的依賴他們的關系。不用手動的建立依賴。

兩種建立模式:一種是全局的、一種是在某一個Bean上進行指定

全局的:

<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
        http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName"
>
           

在某一Bean上直接使用

no

就是沒有自動裝配,必須手動管理它們的依賴關系。

byName

使用名稱一緻的方式進行裝配

例如:在XML檔案中寫了代碼一的方式,那麼需要在service中引入 dao這個類時需要使用相同的名字,如代碼二 private Dao dao 高亮的部分

代碼一

<bean id="dao" class="com.dao.daoImpl"/>
    <bean id="service" class="com.sevice.Service" autowire="byName"/>
           

代碼二

public class Service {
   ''' private Dao dao;'''

    public void prient(){
        dao.query();
    }

    public void setDao(Dao dao) {
        this.dao = dao;
    }
}
           

byType

使用類型一緻的方式進行裝配,就是找相同類型的類進行裝配。

代碼塊一中裝配時回去找代碼塊二中一緻的代碼。

代碼塊一

<bean id="dao" class="com.dao.daoImpl"/>
 <bean id="service" class="com.sevice.Service" autowire="byType"/>
           

代碼塊二

public class Service {
    private Dao dao;

    public void prient(){
        dao.query();
    }

    public void setDao(Dao dao) {
        this.dao = dao;
    }
}
           

會出現一中問題就是兩個實作類同時對一個接口實作了,在依賴于這個接口的類中自動裝配實作類時會找不到具體指定哪一個實作類。

例如

<bean id="dao" class="com.dao.daoImpl"/>
    <bean id="dao2" class="com.dao.daoImpl2"/>
    <bean id="service" class="com.sevice.Service" autowire="byType"/>
           

注意byType和byName都是使用的set注入的方式。還有一種的構造器注入

constructor

構造器注入的方式使用的是相同的名稱來進行注入的。

代碼一

代碼二

public class Service {
    private Dao dao;
    public Service(Dao dao) {
        this.dao = dao;
    }
    public void prient(){
        dao.query();
    }
}
           

@Autowired

自動裝配依賴還可以使用注解的方式,有Spring提供的 @Autowired注解和javax.annotation提供的@Resource

@Autowired放在屬性上為Set注入,它首先會根據類型(byType)進行查找,如果找不到以名稱(byName)進行查找。使用方式:

@Autowired
    private Dao daoImpl;
           

若Dao隻有一個實作類則按照Dao類型找出其相應的實作類,作為依賴的具體實作。若有兩個實作類則Spring會将實作類的首字母變小寫然後和引用變量進行比較進而找出一緻的類。例如dao有兩個實作類代碼二和代碼三

代碼一

public interface Dao {
    void query();
}
           

代碼二

@Component
public class daoImpl implements Dao {
    public void query() {
        System.out.println("Impl");
    }
}

           

代碼三

@Component
public class daoImpl2 implements Dao {
    public void query() {
        System.out.println("Impl2");
    }
}
           

如果寫成代碼四的方式引入依賴

@Service
public class ServiceImpl {

    @Autowired
    private Dao dao;
    public void prient(){
        dao.query();
    }
    
}
           

則會報錯

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'serviceImpl': Unsatisfied dependency expressed through field 'dao'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.dao.Dao' available: expected single matching bean but found 2: daoImpl,daoImpl2
           

在代碼五中你隻要定義一個和其中一個實作類名稱相同即可

@Service
public class ServiceImpl {

    @Autowired
    private Dao daoImpl;
    public void prient(){
        daoImpl.query();
    }
}

           

當然若隻有一個實作類,則完全可以按照類型引入引用,而不用關注名稱。

如果需要使用别名進行依賴注入的話需要使用@Qualifier(“dao2”)和@Autoaware一起使用。

@Resource

@Resource是javaAPI提供的注解,可以直接使用 @Resource(name = “dao2”)進行依賴注入,也可以不指定名稱。使用的是類的的首字母小寫生成的依賴名稱進行查找注入,它會先找與定義依賴引用變量一緻的,若找不到則會找相同類型的的類進行注入。

自動裝配的優缺點

Autowiring has the following advantages:

Autowiring can significantly reduce the need to specify properties or constructor arguments. (Other mechanisms such as a bean template discussed elsewhere in this chapter are also valuable in this regard.)

Autowiring can update a configuration as your objects evolve. For example, if you need to add a dependency to a class, that dependency can be satisfied automatically without you needing to modify the configuration. Thus autowiring can be especially useful during development, without negating the option of switching to explicit wiring when the code base becomes more stable.
           

Consider the limitations and disadvantages of autowiring:

Explicit dependencies in property and constructor-arg settings always override autowiring. You cannot autowire so-called simple properties such as primitives, Strings, and Classes (and arrays of such simple properties). This limitation is by-design.

Autowiring is less exact than explicit wiring. Although, as noted in the above table, Spring is careful to avoid guessing in case of ambiguity that might have unexpected results, the relationships between your Spring-managed objects are no longer documented explicitly.

Wiring information may not be available to tools that may generate documentation from a Spring container.

Multiple bean definitions within the container may match the type specified by the setter method or constructor argument to be autowired. For arrays, collections, or Maps, this is not necessarily a problem. However for dependencies that expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean definition is available, an exception is thrown.
           

注:Spring在預設情況下會用單例模式将所有的Bean加載到容器中,如果開啟懶加載也就是在用到的時候才加載的方式可以使用。設定懶加載的方式: