1. 程式人生 > >Spring第八章:Spring自動註入

Spring第八章:Spring自動註入

args 當前 com 滿足 pri 生效 成功 abstract 屬性

.自動註入

  1.Spring 配置文件中對象名和 ref=idid 名相同使用自動註入,可以不配置<property/>

  2.兩種配置辦法

    2.1 <bean>中通過 autowire=”” 配置,只對這個<bean>生效

    2.2 <beans>中通過 default-autowire=””配置,表當當前文件中所<bean>都是全局配置內容

    2.3 自動註入代碼

      2.3.1測試自動註入的實體類,老師和學生類

package com.suncl.model;

import org.springframework.beans.factory.annotation.Value;

/**
 * Created by SCL-PC on 2019/3/5.
 */

public class Teacher {
    private String name ="張三";
    public String getName() {
        return name;
    }
    public void setName(String name) {
        
this.name = name; } @Override public String toString() { return "Teacher{" + "name=‘" + name + ‘\‘‘ + ‘}‘; } }


package com.suncl.model;

import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;

/**
* Created by SCL-PC on 2019/3/5.
*/
public class Student {
private String name = "李四";
private Teacher teacher22;

public Student(Teacher teacher22){
this.teacher22 = teacher22;
}

public Student() {
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

public Teacher getTeacher22() {
return teacher22;
}

public void setTeacher22(Teacher teacher22) {
this.teacher22 = teacher22;
}

@Override
public String toString() {
return "Student{" +
"name=‘" + name + ‘\‘‘ +
", teacher=" + teacher22 +
‘}‘;
}
}
 

      2.3.2配置文件

<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" >

<!--默認的註入方式 配置之後取beans的 default-autowire 如果默認的也沒有配置就等同no-->
<bean id="student1" class="com.suncl.model.Student" autowire="default"></bean>

<!--不自動註入-->
<bean id="student2" class="com.suncl.model.Student" autowire="no"></bean>

<!--按照名稱自動註入 也就是id-->
<bean id="student3" class="com.suncl.model.Student" autowire="byName"></bean>

<!--按照類型自動註入 註意這裏如果有兩個相同的註入類型會報錯-->
<bean id="student4" class="com.suncl.model.Student" autowire="byType"></bean>

<!--按照構造器自動註入-->
<bean id="student5" class="com.suncl.model.Student" autowire="constructor"></bean>


<bean id="teacher" class="com.suncl.model.Teacher"></bean>

<!--寫來測試按照類型註入的時候出錯的場景-->
<!--<bean id="teacher2" class="com.suncl.model.Teacher"></bean>-->

</beans>

      2.3.3 測試類

package com.suncl.test;

import com.suncl.model.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by SCL-PC on 2019/2/28.
 */
public class Test {

    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student)ac.getBean("student3",Student.class);
        System.out.println(student.toString());

    }


}

    3.autowire=”” 可取值

      3.1 default: 默認值,根據全局 default-autowire=””值.默認全局和局部都沒有配置情況下,相當於 no

  <!--默認的註入方式 配置之後取beans的 default-autowire 如果默認的也沒有配置就等同no-->
<bean id="student1" class="com.suncl.model.Student" autowire="default"></bean>

Student student = (Student)ac.getBean("student1",Student.class);
Student{name=‘李四‘, teacher=null}

      運行結果可以看到 老師實體沒有完成註入 但是我們如果配置了一個全局 default-autowire=””再看下結果

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

    <!--默認的註入方式 配置之後取beans的 default-autowire 如果默認的也沒有配置就等同no-->
    <bean id="student1" class="com.suncl.model.Student" autowire="default"></bean>
Student{name=‘李四‘, teacher=Teacher{name=‘張三‘}} 註入成功 

      3.2 no: 不自動註入

 <!--不自動註入-->
 <bean id="student2" class="com.suncl.model.Student" autowire="no"></bean>
Student student = (Student)ac.getBean("student2",Student.class);
Student{name=‘李四‘, teacher=null}

      不註入就只能是null了

      3.3 byName: 通過名稱自動註入.Spring 容器中找類的 Id 

<bean id="student3" class="com.suncl.model.Student" autowire="byName"></bean>
Student student = (Student)ac.getBean("student3",Student.class);
Student{name=‘李四‘, teacher=Teacher{name=‘張三‘}}

       可以看到按照名稱註入了,怎麽理解名稱註入呢。假設我們現在修改下bean的id

<bean id="teacher22" class="com.suncl.model.Teacher"></bean>
 Student student = (Student)ac.getBean("student3",Student.class);
Student{name=‘李四‘, teacher=null}

      然後再執行測試類,發現無法註入成功。

      然後我們再去修改學生類的屬性,修改teacher屬性為teacher22完成註入

   private Teacher teacher22;
  public Teacher getTeacher22() {
        return teacher22;
    }

    public void setTeacher22(Teacher teacher22) {
        this.teacher22 = teacher22;
    }
Student student = (Student)ac.getBean("student3",Student.class);
Student{name=‘李四‘, teacher=Teacher{name=‘張三‘}}

      如下即可註入成功,所以byName的註入方式要求bean的id 和註入類的屬性名稱一致即可

      3.4 byType: 根據類型註入.

 <bean id="student4" class="com.suncl.model.Student" autowire="byType"></bean>
Student student = (Student)ac.getBean("student4",Student.class);
Student{name=‘李四‘, teacher=Teacher{name=‘張三‘}}

      特別註意容器裏面不可以出現兩個相同類型的bean

    <!--寫來測試按照類型註入的時候出錯的場景-->
    <bean id="teacher2" class="com.suncl.model.Teacher"></bean>

      例如我這邊就定義了兩個相同類型的Teacher實體。那麽spring會出現錯誤

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.suncl.model.Teacher] is defined: expected single matching bean but found 2: teacher22,teacher2
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1288)
    ... 18 more
expected single matching bean but found 2: teacher22,teacher2。預期是一個滿足的bean,但是找到了2個,立馬就懵逼了。

      3.5 constructor: 根據構造方法註入.

        3.5.1 提供對應參數的構造方法(構造方法參數中包含註入對戲那個)

        3.5.2 底層使用 byName, 構造方法參數名和其他<bean>id

 public Student(Teacher teacher22){
        this.teacher22 = teacher22;
 }

        提供一個屬性名稱的構造器

  <!--按照構造器自動註入-->
<bean id="student5" class="com.suncl.model.Student" autowire="constructor"></bean>
Student student = (Student)ac.getBean("student5",Student.class);
Student{name=‘李四‘, teacher=Teacher{name=‘張三‘}}

        註意:這裏定義了屬性名稱構造器之後,spring會提示有上面的byName和byType會出現錯誤,需要再手動添加一個無參構造器。java默認會為所有的類提供無參構造器,

        但是如果你自己寫了任何有參數的構造器,那麽默認的無參構造器就沒有了。

Spring第八章:Spring自動註入