之前實例化對象都是在Spring的xml配置文件中進行配置,每新增一個對象就需要配置一次,這樣就會特別麻煩,也會造成xml配置文件特別大,再者不利於開發,影響開發效率,所以出現了註解裝配JavaBean的方式。使用註解,可以減少代碼的開發量。
在Spring中,默認是禁用註解配置的,如果想要開啓註解,需要進行配置,開啓註解掃描。
開啓註解掃描的方式有以下兩種:
<context:component-scan>組件掃描
<context:annotation-config>註解配置
二者的區別是:
<context:annotation-config>用於激活那些已經在spring容器裏註冊過(配置過)的bean(無論是通過xml的方式還是通過package sanning的方式)上面的註解。
<context:component-scan>除了具有<context:annotation-config>的功能之外,還可以在指定的package下掃描以及註冊javabean .
所以一般使用<context:component-scan>。
例:
<!-- 開啓註解掃描 -->
<context:component-scan base-package="com.gxj" />
base-package 屬性指定一個需要掃描的基類包,Spring 容器將會掃描這個基類包裏及其子包中的所有類. 當需要掃描多個包時, 可以使用逗號分隔.
也可以使用resource-pattern屬性來過濾特定的類。配置示例如下:
<context:component-scan base-package="com.gxj" resource-pattern="three/*.class"/>
上述配置要求Spring掃描com.gxj 下的three註解配置bean的關聯關係。
< context:component-scan> 元素還會自動註冊 AutowiredAnnotationBeanPostProcessor 實例, 該實例可以自動裝配具有 @Autowired 和 @Resource 、@Inject註解的屬性.包下的所有類。一般使用@Autowired。
通過註解的方式配置Bean是通過掃描的動作來完成的。在xml文件中通過配置(包括一個路徑),Spring就會在這個路徑中掃描、偵測以及實例化具有特定註解的組件。
這些註解包括:
@Component: 基本註解,標識了一個受Spring管理的組件
@Repository:標識持久層組件
@Service: 標識服務層(業務層)組件
@Controller: 標識表現層組件
這些註解的功能都是一樣的,都是實例化對象,只是基於實際項目開發的架構,在不同層級進行區分和使用。
註解默認命名規則:
我們使用註解配置bean的時候,並沒有指定bean的id,那麼spring幫我們創建bean的時候會給一個默認的id,id爲類名首字母小寫。如TestController實例化對象之後是 testController
我們也可以指定bean的名稱(id),使用註解的value屬性,如@Service(value=”myService”)
value屬性是註解的默認屬性,可以省略,即@Service(“myService”)
例:
項目結構如下:
在原來的基礎上新增spring-aop-3.2.4.RELEASE.jar。
在applicationContext.xml配置文件中配置(需要引入context約束):
<?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"
xmlns:p="http://www.springframework.org/schema/p"
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.gxj" />
<!-- <context:component-scan base-package="com.gxj" resource-pattern="three/*.class"/> -->
<!-- <bean id="school" class="com.gxj.three.School"></bean> -->
<!-- <bean id="teacher" class="com.gxj.three.Teacher"></bean> -->
<!-- <bean id="student" class="com.gxj.three.Student"></bean> -->
</beans>
實例對象:
Teacher.java:
package com.gxj.three;
import org.springframework.stereotype.Component;
@Component
public class Teacher {
public void teach() {
System.out.println("老師:上課!");
}
}
----------
Student.java:
package com.gxj.three;
import org.springframework.stereotype.Service;
@Service
public class Student {
public void study() {
System.out.println("學生:老師好!");
}
}
----------
School.java:
package com.gxj.three;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class School {
@Autowired
private Teacher teacher;
@Resource
private Student student;
public void inClass() {
teacher.teach();
student.study();
System.out.println("老師:同學們好!");
}
}
測試:
SchoolTest.java:
package com.gxj.three;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SchoolTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("com/gxj/three/applicationContext.xml");
School school = (School) context.getBean("school");
school.inClass();
}
}
結果: