1. 程式人生 > >Spring基礎——在Spring Config 檔案中配置 Bean

Spring基礎——在Spring Config 檔案中配置 Bean

一、基於 XML 的 Bean 的配置——通過全類名(反射)

<bean

<!-- id: bean 的名稱在IOC容器內必須是唯一的若沒有指定,則自動的將全限定類名作為 改 bean 的名稱-->id="hello"

<!-- 通過全類名的方式來配置 bean -->class="com.atguigu.spring.helloworld.HelloWorld">

</bean>

1.通過屬性注入

基於set函式的依賴注入

即通過 setXxx() 方法注入 Bean 的屬性值或依賴的物件。

使用 <property name="" value="" ref=""/>

 元素,其中 name 值為對應 Bean 屬性名稱,value 指定對應屬性值,ref 引用其他 Bean,value 屬性和 ref 屬性不可以同時存在。

也可以通過 <value></value> 子節點的方式指定屬性值。

e:

<bean id="helloWorld" class="com.nucsoft.spring.helloworld.HelloWorld">
  <property name="hello" value="spring"/>
  <property name="world">
    <value>spring</value>
  </property>
</bean>

注意:在此種方式下,要配置的 Bean 必須存在空參構造器。

 

student.java

package com.hzyc.springlearn.bean;

/**
 * @author xuehj2016
 */
public class Student {

	private int id;
	private String name;
	private Teacher teacher;

	public Student() {
		System.out.println("student ins create");
	}

	public Student(int id, Teacher teacher) {
		this.id = id;
		this.teacher = teacher;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

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

	public Teacher getTeacher() {
		return teacher;
	}

	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}

}

teacher.java

package com.hzyc.springlearn.bean;

public class Teacher {

	private String tname;

	public String getTname() {
		return tname;
	}

	public void setTname(String tname) {
		this.tname = tname;
	}
	
}

 spring-config.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
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="student" class="com.hzyc.springlearn.bean.Student">
        <property name="id" value="123"/>
        <property name="name" value="張三"/>
        <property name="teacher">
            <bean class="com.hzyc.springlearn.bean.Teacher">
                <property name="tname" value="李老師"/>
            </bean>
        </property>
    </bean>
    <bean id="teacher" class="com.hzyc.springlearn.bean.Teacher">
        <property name="tname" value="王老師"/>
    </bean>
</beans>

application.java

package com.hzyc.springlearn;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hzyc.springlearn.bean.Student;
import com.hzyc.springlearn.bean.Teacher;

/**
 * @author xuehj2016
 */
public class Application2 {

	public static void main(String[] args) {
		ApplicationContext app = new ClassPathXmlApplicationContext("spring-config2.xml");
		Student stu= app.getBean(Student.class);
		Teacher tea= app.getBean(Teacher.class);
		System.out.println(stu.getName());
		System.out.println(stu.getTeacher());
		System.out.println(stu.getTeacher().getTname());
		System.out.println("----------------");
		System.out.println(tea);
		System.out.println(tea.getTname());
	}
}

 

2.通過構造器注入

基於建構函式的依賴注入

通過構造方法注入屬性值或依賴的物件。

使用 <constructor-arg value="" index="" name="" ref="" type=""/> 元素,value 屬性為對應的引數指定值,ref 引用其他 Bean。不可同時存在。

通過 name 屬性、index 屬性、type屬性提供了三種注入方式:

(1)name:按照構造器引數名匹配入參

<bean id="car1" class="com.nucsoft.spring.helloworld.Car">
  <constructor-arg name="brand" value="奧迪"/>
  <constructor-arg name="corp" value="上海"/>
  <constructor-arg name="price" value="400000"/>
</bean>

(2)index:按照索引匹配入參

<bean id="car2" class="com.nucsoft.spring.helloworld.Car">
  <constructor-arg index="0" value="大眾"/>
  <constructor-arg index="1" value="10000"/>
</bean>

(3)type:按照型別匹配入參

<bean id="car3" class="com.nucsoft.spring.helloworld.Car">
  <constructor-arg type="java.lang.String" value="寶馬"/>
  <constructor-arg type="double" value="200000"/>
</bean>

注意:Spring 雖然提供了通過構造器的方式進行注入,但是並不推薦使用此種方式。

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

    <bean id="student" class="com.hzyc.springlearn.bean.Student">
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" ref="teacher"/>
    </bean>
    <bean id="teacher" class="com.hzyc.springlearn.bean.Teacher">
        <property name="tname" value="王老師"/>
    </bean>
</beans>

application.xml

package com.hzyc.springlearn;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hzyc.springlearn.bean.Student;
import com.hzyc.springlearn.bean.Teacher;

/**
 * @author xuehj2016
 */
public class Application {

	public static void main(String[] args) {
		ApplicationContext app = new ClassPathXmlApplicationContext("spring-config.xml");
		Student stu= app.getBean(Student.class);
		Teacher tea= app.getBean(Teacher.class);
		System.out.println(stu.getName());
		System.out.println(stu.getTeacher());
		System.out.println(stu.getTeacher().getTname());
		System.out.println("----------------");
		System.out.println(tea);
		System.out.println(tea.getTname());
	}
}

3.細節問題

(1)若注入的屬性值包含特殊字元,可以使用 <![CDATA[]]> 包含該屬性值。

如:

<bean id="car4" class="com.nucsoft.spring.Car">
  <property name="brand">
    <value><![CDATA[<BM>]]> </value>
  </property>
  <property name="corp" value="德國"/>
  <property name="maxSpeed" value="230"/>
  <property name="price" value="20000000"/>
</bean>

(2)可以通過 <ref> 元素或 ref 屬性為 Bean 的屬性或構造器指定對 Bean 的引用。

 如:

e1:

<bean id="service" class="com.nucsoft.spring.Service"/>
<bean id="action" class="com.nucsoft.spring.Action">
    <property name="service" ref="service"/>
</bean>

e2:

<bean id="feather" class="com.nucsoft.spring.Feather">
  <property name="length" value="13"/>
</bean>

<bean id="bird" class="com.nucsoft.spring.Bird">
  <constructor-arg name="birdName" value="smallBird"/>
  <constructor-arg name="feather" ref="feather"/>
</bean>

(3)內部Bean:可以在屬性或構造器裡包含 Bean 的宣告,內部 Bean 不需要指定 id,同時在別的地方也無法引用。

 如:

e1:

<bean id="action" class="com.nucsoft.spring.Action">
  <property name="service">
  <bean class="com.nucsoft.spring.Service"/>
  </property>
</bean>

e2:

<bean id="bird" class="com.nucsoft.spring.Bird">
  <constructor-arg name="birdName" value="smallBird"/>
  <constructor-arg name="feather">
    <bean class="com.nucsoft.spring.Feather">
      <property name="length" value="13"/>
    </bean>
  </constructor-arg>
</bean>

4.為引用型別(字串或物件)注入 Null 值

<bean id="bird" class="com.nucsoft.spring.Bird">
  <constructor-arg name="birdName" value="smallBird"/>
  <constructor-arg name="feather">
    <null/>
   </constructor-arg>
</bean>

5.為級聯屬性注入

(1)通過屬性

複製程式碼

<bean id="feather" class="com.nucsoft.spring.Feather">
  <property name="length" value="44"/>
</bean>

<bean id="bird" class="com.nucsoft.spring.Bird">
  <property name="birdName" value="smallBird"/>
  <property name="feather" ref="feather"/>
  <property name="feather.length" value="23"/>
</bean>

複製程式碼

(2)通過構造器

複製程式碼

<bean id="feather" class="com.nucsoft.spring.Feather">
    <property name="length" value="44"/>
</bean>
<bean id="bird2" class="com.nucsoft.spring.Bird">
    <constructor-arg name="birdName" value="bigBird"/>
    <constructor-arg name="feather" ref="feather"/>
    <property name="feather.length" value="33"/>
</bean>

複製程式碼

注意:設定級聯屬性的前提是,級聯屬性所屬物件已經被注入到容器中。同時需要為級聯屬性所屬物件提供 getXxx() 方法。

6.集合屬性

(1)集合性質的型別:List,Set,Map 和 陣列

(2)使用 <list>,<set>,<map> 來配置集合屬性,其中陣列和 List 都使用 <list>

(3)List:通過引用外部 Bean 或 建立內部 Bean 的方式

複製程式碼

<bean id="department" class="com.nucsoft.spring.Department">
  <property name="deptName" value="dept01"/>
</bean>

<bean id="company" class="com.nucsoft.spring.Company">
  <property name="companyName" value="ICBC"/>
  <property name="departments">
    <list>
      <ref bean="department"/>
      <bean class="com.nucsoft.spring.Department">
        <property name="deptName" value="dept02"/>
      </bean>
    </list>
  </property>
</bean>

複製程式碼

測試:

複製程式碼

private ApplicationContext ctx = null;

@Before
public void init() {
  ctx = new ClassPathXmlApplicationContext("spring/ApplicationContext.xml");
}

@Test
public void test01() {
  Company com = ctx.getBean(Company.class);
  System.out.println(com);
}

複製程式碼

輸出:

Company{companyName='ICBC', departments=[Department{deptName='dept01'}, Department{deptName='dept02'}]}

(4)Set:與 List 類似。不做重複說明。

(5)Map: 在<map> 標籤中使用多個 <entry> 子標籤:簡單字面值使用屬性 key 和 value 來定義,Bean 的引用通過 key-ref 和 value-ref 屬性定義。

如:

複製程式碼

<bean id="emp02" class="com.nucsoft.spring.Employee">
  <property name="employeeName" value="emp02"/>
  <property name="age" value="23"/>
</bean>

<bean id="department" class="com.nucsoft.spring.Department">
  <property name="deptName" value="dept01"/>
</bean>
<bean id="department02" class="com.nucsoft.spring.Department">
  <property name="deptName" value="dept02"/>
</bean>

<bean id="company" class="com.nucsoft.spring.Company">
  <property name="companyName" value="ICBC"/>
  <property name="departments">
    <map>
      <entry key-ref="department" value-ref="emp01"/>
      <entry key-ref="department02" value-ref="emp02"/>
    </map>
  </property>
  <property name="strs">
    <map>
      <entry key="key01" value="value01"/>
      <entry key="key02" value="value02"/>
    </map>
  </property>
</bean>

複製程式碼

測試:

複製程式碼

private ApplicationContext ctx = null;

@Before
public void init() {
  ctx = new ClassPathXmlApplicationContext("spring/ApplicationContext.xml");
}

@Test
public void test01() {
  Company com = ctx.getBean(Company.class);
  System.out.println(com);
}

複製程式碼

輸出:

Company{companyName='ICBC', departments={Department{deptName='dept01'}=Employee{employeeName='emp01', age=12}, Department{deptName='dept02'}=Employee{employeeName='emp02', age=23}}}

注意:不能在 <entry> 標籤中定義 Bean 標籤,不支援。

(6)Properties 型別的屬性:和 Map 類似,在 <props> 標籤中使用 <prop> 子標籤, 每個 <prop> 子標籤必須定義 key 屬性。

複製程式碼

<bean id="DataSourceId" class="com.nucsoft.spring.DataSourceBean">
  <property name="propertiesInfo">
    <props>
      <prop key="user">root</prop>
      <prop key="password"></prop>
      <prop key="jdbcUrl">jdbc:mysql:///test</prop>
      <prop key="driverClass">com.mysql.jdbc.Driver</prop>
    </props>
  </property>
</bean>

複製程式碼

7.定義單獨的集合 Bean

使用基本的集合標籤定義集合時,不能將集合作為獨立的 Bean 定義,導致其他 Bean 無法引用該集合,所以無法在不同的 Bean 之間共用。

可以使用 util schema 裡的集合標籤定義獨立的集合 Bean。需要注意的是,定義的集合 Bean 與 <bean> 標籤是同級別的。

複製程式碼

<bean id="company" class="com.nucsoft.spring.Company">
  <property name="companyName" value="ICBC"/>
  <property name="departments" ref="departments"/>
</bean>

<util:list id="departments">
  <bean class="com.nucsoft.spring.Department">
    <property name="deptName" value="dept01"/>
  </bean>
  <ref bean="department02"/>
</util:list>

複製程式碼

可以定義到外部的集合 Bean 有:

8.使用 p 名稱空間,簡化 XML 配置檔案

<bean id="bird3" class="com.nucsoft.spring.Bird" p:birdName="smallBird" p:feather-ref="feather"/>

二、基於 XML 的 Bean 的配置——通過工廠方法

1.通過靜態工廠方法

直接呼叫某一個類的靜態方法,可以返回一個 Bean 的例項。通過 class 屬性來指定全類名,使用 factory-method 來指定生成 bean 的靜態方法。使用 constructor-arg 為靜態方法傳入引數。如:

<bean class="java.text.DateFormat" id="dateFormat" factory-method="getDateInstance">
  <constructor-arg value="1"/>
</bean>
@Test
public void test04() {
  DateFormat dateFormat = (DateFormat) ctx.getBean("dateFormat");
  System.out.println(dateFormat);
}

適用情況:官方或第三方提供的通過靜態方法生成 bean 物件,不需要我們再建立,對應的 Bean 類一般是通過 newInstance 軟編碼的方式來建立。

2.通過例項工廠方法:將物件建立的過程封裝到另外一個物件的方法裡。

(1)首先要建立和配置一個含有工廠方法的 Bean

(2)在另一個 bean 配置中呼叫含有工廠方法 bean 的非 static 方法(即工廠方法)來返回一個 bean 的例項,factory-bean:指向已經建立好的工廠 bean ,factory-method:例項化工廠方法,construtor-arg:為例項工廠方法傳入引數。

如:

工廠 Bean 的配置:

<bean class="java.text.SimpleDateFormat" id="simpleDateFormat">
  <constructor-arg value="yyyy-MM-dd"/>
</bean>

目標 Bean 的配置:

<bean factory-bean="simpleDateFormat" factory-method="parse" id="date">
  <constructor-arg value="2012-02-24"/>
</bean>

測試:

@Test
public void test05() {
  Date date = (Date) ctx.getBean("date");
  System.out.println(date);
}

控制檯輸出:

Fri Feb 24 00:00:00 CST 2012

三、基於 XML 的 Bean 的配置——通過 FactoryBean 配置 Bean

1.Spring 中有兩類 Bean,一種是普通 Bean,另外一種是工廠 Bean,即 FactoryBean

2.工廠 Bean 與普通 Bean 不同,其返回的物件不是指定類的一個例項,其返回的是該工廠 Bean 的 getObject() 方法返回的物件

3.具體操作

(1)目標工廠 Bean 需要實現 FactoryBean 介面

(2)返回的物件為 getObject() 方法返回的物件。

如:

工廠 Bean:

複製程式碼

/**
 * @author solverpeng
 * @create 2016-07-19-11:45
 */
public class DepartmentFactoryBean implements FactoryBean<Department>{
    @Override
    public Department getObject() throws Exception {
        Department department = new Department();
        department.setDeptName("dept01");
        department.setEmployee(new Employee());
        return department;
    }

    @Override
    public Class<?> getObjectType() {
        return Department.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

複製程式碼

Spring Config 配置:

<bean class="com.nucsoft.spring.bean.DepartmentFactoryBean" id="department"/>

測試:

@Test
public void test06() {
  Department department = (Department) ctx.getBean("department");
  System.out.println(department);
}

三、基於註解的 Bean 的配置

前提:需要匯入 spring-aop-4.0.0.RELEASE.jar 包

1.在 classpath 中掃描元件(component scanning):Spring 能夠從 classpath 下自動掃描和例項化具有特定註解的元件。

2.特定的元件包括:

(1)@Component:基本註解,標識了一個受 Spring 管理的元件

(2)@Respository:標識持久層元件

(3)@Service:標識服務層元件

(4)@Controller :標識表現層元件

3.對於掃描到的元件,Spring 有預設的命名策略:使用簡短類名,第一個字母小寫。也可以通過 value 屬性指定名稱。

4.當在元件類上使用了特定註解後,還需要在 Spring 的配置檔案中宣告 <context:component-scan>。

屬性:

base-package:指定要掃描的基類包,Spring會自動掃描這個基類包及其子包中的所有類。當需要掃描多個包是,可以使用逗號進行分割。

如:

<context:component-scan base-package="com.nucsoft.spring"/>

resource-pattern:若需要掃描基包下指定的類,可以使用該屬性過濾特定的類。預設是:"**/*.class"。

如:

<context:component-scan base-package="com.nucsoft.spring" resource-pattern="component/*.class" />

<context:include-filter type="" expression=""/> 子節點表示要包含的目標類

<context:exclude-filter type="" expression=""/> 子節點表示要排出在外的目標類  

可以同時包含多個 <context:include-filter type="" expression=""/> 和 <context:exclude-filter type="" expression=""/> 子節點

屬性 type:表示支援不同型別的過濾

annotation:所有標註某註解的類。該型別採用目標類是否標註了某註解進行過濾

e:所有在基包下標註 @Controller 註解的類都不被掃描

<context:component-scan base-package="com.nucsoft.spring">
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

assinable:所有繼承或擴充套件某個特定的類進行過濾

e:所有繼承或擴充套件 Person 類的類都不被掃描

<context:component-scan base-package="com.nucsoft.spring" resource-pattern="component/*.class">
  <context:exclude-filter type="assignable" expression="com.nucsoft.spring.bean.Person"/>
</context:component-scan>

四、基於註解來裝配 Bean 的屬性

1.<context:component-scan> 還會自動註冊 AutowiredAnnotationBeanPostProcessor 例項,該例項可以自動裝配具有 @Autowired 和 @Resource、@Inject 註解的屬性。

[email protected] 註解

自動裝配目標 Bean 的 Bean 屬性(該屬性為一個 Bean 的例項,該 Bean 為在 IOC 容器中存在的 Bean)

(1)可以對屬性標註該註解。如:

/**
 * @author solverpeng
 * @create 2016-07-19-16:49
 */
@Component
public class Department {
    private String deptName;

    @Autowired
    private Employee employee;
    @Autowired
    private Address address;

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String toString() {
        return "Department{" +
                "deptName='" + deptName + '\'' +
                ", employee=" + employee +
                ", address=" + address +
                '}';
    }
}

複製程式碼

(2)可以對方法標註該註解,方法引數為要自動裝配的型別,可以是任意方法

複製程式碼

/**
 * @author solverpeng
 * @create 2016-07-19-16:49
 */
@Component
public class Department {
    private String deptName;
    private Employee employee;
    private Address address;

    @Autowired
    public void setAddress(Address address) {
        this.address = address;
    }

    @Autowired
    public void abc(Employee employee) {
        this.employee = employee;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String toString() {
        return "Department{" +
                "deptName='" + deptName + '\'' +
                ", employee=" + employee +
                ", address=" + address +
                '}';
    }
}

複製程式碼

(3)可以對構造器標註該註解,方法引數為要自動裝配的型別。

複製程式碼

/**
 * @author solverpeng
 * @create 2016-07-19-16:49
 */
@Component
public class Department {
    private String deptName;
    private Employee employee;
    private Address address;

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Autowired
    public Department(Employee employee, Address address) {
        this.employee = employee;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Department{" +
                "deptName='" + deptName + '\'' +
                ", employee=" + employee +
                ", address=" + address +
                '}';
    }
}

複製程式碼

注意:

使用 @Autowired 自動匹配時,如果只匹配到一個的情況下:

按照型別進行匹配

如果匹配到多個:

標記有 primary="true" 的 bean 有限,不能同時出現多個 primary="true" 的相同型別的 bean。否則:UnsatisfiedDependencyException

若都沒有 primary 屬性,在按照 @Autowired 標註的構造器或方法 的引數名稱進行匹配 Bean。若還沒有匹配到,則報:UnsatisfiedDependencyException異常。

具體參見:

org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates

org.springframework.beans.factory.support.DefaultListableBeanFactory#determinePrimaryCandidate

(4)若某一個屬性允許不被設定,可以設定 @Autowired 註解的 required 屬性為 false。

(5)@Qualifier 註解:Spring 允許對方法的入參或屬性標註 @Qualifier 註解。@Qualifier 註解裡提供 Bean 的名稱。

如:

屬性處:

@Autowired
@Qualifier("address2")
private Address address;

方法處:

@Autowired
public Department(Employee employee, @Qualifier("address2") Address address) {
  this.address = address;
  this.employee = employee;
}

(6)@Autowired 註解可以標識在陣列型別的屬性上,此時會把所有匹配的 Bean 進行自動裝配

(7)@Autowired 註解可以標識在集合屬性上,此時會將集合型別對應的 Bean 進行自動裝配

(8)@Autowired 註解可以標識在 Map 上,若 key 為 String,則此時會將 value 對應的 Bean 的型別進行自動裝配

 [email protected] 註解

(1)如果說 @Autowired 屬性是按照型別進行自動裝配的,那麼 @Resource 註解可以看成是按照名稱進行裝配的。

@Resource 註解要求提供一個 Bean 名稱的屬性,若該屬性為空,則自動採用標註出的變數或方法名作為 Bean 的名稱。

注意:不能標註於構造器。

student.java

package com.hzyc.springlearn.bean;

import javax.annotation.Resource;

public class Student {
    private int id;
    private String name;

    @Resource
    private Teacher teacher;

    public Student() {
        System.out.println("student ins create");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
}

teacher.java

package com.hzyc.springlearn.bean;

public class Teacher {
	private String tname;

	public String getTname() {
		return tname;
	}

	public void setTname(String tname) {
		this.tname = tname;
	}
}

spring-config.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"
       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">
    <context:annotation-config/>

    <bean id="student" class="com.hzyc.springlearn.bean.Student">
        <property name="id" value="1"/>
        <property name="name" value="張三"/>
    </bean>

    <bean id="teacher" class="com.hzyc.springlearn.bean.Teacher">
        <property name="tname" value="王老師"/>
    </bean>
</beans>

 application.java

package com.hzyc.springlearn;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hzyc.springlearn.bean.Student;
import com.hzyc.springlearn.bean.Teacher;

public class Application {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        Student student = applicationContext.getBean(Student.class);
        Teacher teacher = applicationContext.getBean(Teacher.class);
        System.out.println(student.getName());
        System.out.println(student.getTeacher());
        System.out.println(student.getTeacher().getTname());
        System.out.println("----------------");
        System.out.println(teacher);
        System.out.println(teacher.getTname());
    }
}

[email protected] 註解

和 @Autowire的 註解一樣也是按照型別匹配注入的 Bean ,但是沒有 required 屬性。

5.最後,對比一下@Resource和@Autowired

(1)@Resource預設是按照名稱來裝配注入的,只有當找不到與名稱匹配的bean才會按照型別來裝配注入

(2)@Autowired預設是按照型別裝配注入的,如果想按照名稱來轉配注入,則需要結合@Qualifier一起使用

(3)@Resource註解是又J2EE提供,而@Autowired是由spring提供,故若要減少系統對spring的依賴建議使用 @Resource的方式;

6.最最後,推薦使用 @Autowired 註解。

 

 

Spring注入內部bean

inner beans 是在其他 bean 的範圍內定義的 bean。在 constructor-argproperty元素內部定義bean,如下所示:

Spring 注入集合

Spring 提供了四種類型的集合的配置元素,如下所示:

元素

描述

<list>

它有助於連線,如注入一列值,允許重複。

<set>

它有助於連線一組值,但不能重複。

<map>

它可以用來注入名稱-值對的集合,其中名稱和值可以是任何型別。

<props>

它可以用來注入名稱-值對的集合,其中名稱和值都是字串型別。

teacher.java

spring-config.xml

執行結果

 

 

常用註解說明

Spring會搜尋顯式指定的路徑下的Java類,然後將帶有特殊Annotation標註的類,全部註冊為Spring Bean

Spring提供如下Annotation來標註Spring Bean

Ø@Controller:標註一個控制器元件類

Ø@Service:標註一個業務邏輯元件類

Ø@Repository:標註一個數據訪問DAO元件類

Ø@Component:泛指元件,當元件不好歸類的時候,我們可以使用這個註解進行標註

 

Spring自動掃描

前面的例子我們都是使用XMLbean定義來配置元件。在一個稍大的專案中,通常會有上百個元件,如果這些這元件採用xmlbean定義來配置顯然會增加配置檔案的體積查詢及維護起來也不太方便。spring2.5為我們引入了元件自動掃描機制,他可以在類路徑底下尋找標註了@Component@Service@Controller@Repository註解的類,並把這些類納入進spring容器中管理它的作用和在xml檔案中使用bean節點配置元件是一樣的要使用自動掃描機制,我們需要開啟以下配置資訊:

<?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">

 

   <context:component-scan base-package="com.hzyc.springlearn"/>

</beans>

其中base-package為需要掃描的包(含子包)。

Spring的自動掃描

1.Teacher

2.Student

3.spring-config.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"

    xmlns:context="http://www.springframework.org/schema/context"

    xsi:schemaLocation="

              http://www.springframework.org/schema/context

                http://www.springframework.org/schema/context/spring-context.xsd

            http://www.springframework.org/schema/beans

            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

     <!-- 自動掃描的基本包 -->

     <context:component-scan base-package="com.hzyc.springlearn" />

</beans>