前面講的方式都是通過XML方式配置bean的,相對於XML方式而言,通過註解的方式配置更加簡潔和優雅,而且和MVC組件化開發的理念十分契合,是開發中常用的配置方式
組件:就是bean
①普通組件:@Component
標識一個受Spring IOC容器管理的組件
②持久化層組件:@Repository
標識一個受Spring IOC容器管理的持久化層組件
③業務邏輯層組件:@Service
標識一個受Spring IOC容器管理的業務邏輯層組件
④表述層控制器組件:@Controller
標識一個受Spring IOC容器管理的表述層控制器組件
寫幾個類,結構如下:
package com.ztt.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
public UserController(){
System.out.println("controller");
}
}
package com.ztt.dao;
public interface UserDao {
}
package com.ztt.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao{
public UserDaoImpl(){
System.out.println("daoImpl");
}
}
package com.ztt.service;
public interface UserService {
}
package com.ztt.service;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
public UserServiceImpl(){
System.out.println("serviceImpl");
}
}
配置文件如下:
<context:component-scan base-package="com.ztt"></context:component-scan>
其中:base-package爲要掃描的包名,建議寫的精確一些,不同的包可以用逗號隔開
component-scan:掃描組件,對設置的包下面的類進行掃描,會將加上註解的類作爲spring的組件進行加載
例如,測試類如下:
package com.ztt.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ztt.controller.UserController;
import com.ztt.dao.UserDao;
import com.ztt.dao.UserDaoImpl;
import com.ztt.service.UserService;
import com.ztt.service.UserServiceImpl;
public class test {
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
UserController uc = ac.getBean("userController", UserController.class);
System.out.println(uc);
UserDao ud = ac.getBean("userDaoImpl", UserDaoImpl.class);
System.out.println(ud);
UserService us = ac.getBean("userServiceImpl", UserServiceImpl.class);
System.out.println(us);
}
}
配置文件:只掃描com.ztt.controller包,所以@Service和@Repository掃描不到
<context:component-scan base-package="com.ztt.controller">
</context:component-scan>
作爲spring的組件進行加載:會自動在spring的配置文件中生成相對於的bean,這些bean的id會以類的首字母小寫爲值
例如,測試類改爲:
public class test {
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
UserController uc = ac.getBean("userController", UserController.class);
System.out.println(uc);
}
}
此時運行成功,結果如下:
controller
<context>還有兩個子標籤:
<context:exclude-filter>:在設定的包結構下,再次通過註解或類型排除某個或某幾個類,使用時需設置use-default-filters="true"(該值爲默認值),因爲需要先掃描,掃描後才能確定需要排除的類
<context:include-filter>:在設定的包結構下,再次通過註解或類型具體包含某個或某幾個類,使用時需設置use-default-filters="false"
切記:一個<context:component-scan>中可以出現多個include,也可以出現多個exclude,但二者不能同時出現
二者中有type和expression屬性,type可以取值爲annotation(註解類型)、aspectj、assignable、custom、regex
例如,①只掃描com.ztt包下註解爲Controller的類
<context:component-scan base-package="com.ztt" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
②只掃描com.ztt包下具體的類型爲UserController的類
<context:component-scan base-package="com.ztt" use-default-filters="false">
<context:include-filter type="assignable" expression="com.ztt.controller.UserController"/>
</context:component-scan>
測試類:
package com.ztt.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
System.out.println(ac);
}
}
此時需加一個jar包spring-aop-4.0.0.RELEASE.jar,否則運行會報錯
運行結果:
controller
daoImpl
serviceImpl
完成組件化管理的過程:
在需要被Spring管理的類上加上相應的註解
在配置文件中,通過<context:component-scan>標籤對所設置的包結構進行掃描,就會將加上註解的類,作爲Spring的組件進行加載
組件就是Spring中管理的bean
作爲Spring的組件進行加載:會自動在Spring的配置文件中生成相對應的bean,這些bean的id會以類的首字母小寫爲值
也可以通過@Controller("beanId")爲自動生成的bean指定id
自動裝配:在需要賦值的非字面量屬性上,加上@Autowired,就可以在Spring容器中,通過不同的方式匹配到相應的bean
@Autowired裝配時,會默認使用byType方式,此時要求Spring容器中只有一個能夠爲其賦值
當byType實現不了裝配時,會自動切換到byName,此時要求Spring容器中,有一個bean的id和屬性名一致
若自動裝配時,匹配到多個能夠賦值的bean,可使用@Qualifier(value="beanId")指定使用的bean
@Autowired和@Qualifier(value="beanId")可以一起作用於一個帶形參的方法上,此時,@Qualifier(value="beanId")所指定的bean作用於形參