前面讲的方式都是通过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作用于形参