使用注解标识一个类(@Component,@Controller,@Repository,@Service)
//value属性指定当前类的对象在容器中的id @Component(value = "car") public class Car { }在配置文件中配置要扫描的包,Spring会扫描该包及其子包下的所有类(context:component-scan标签)
<context:component-scan base-package="com.dudu.beans"/>指定扫描的资源(resource-pattern属性)
<context:component-scan base-package="com.dudu.beans" resource-pattern="dao/*.class"/>指定排除哪些资源(context:exclude-filter子节点)
<context:component-scan base-package="com.dudu.beans"> <!-- 指定排除有Controller注解的类 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <!-- 指定排除UserDao接口及其所有的实现类 --> <context:exclude-filter type="assignable" expression="com.dudu.beans.dao.UserDao"/> </context:component-scan>指定包含哪些资源,此时要禁用默认的filter(context:include-filter子节点)
<context:component-scan base-package="com.dudu.beans" use-default-filters="false"> <!-- 指定只包含有Controller注解的类--> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <!-- 指定只包含UserDao接口及其所有的实现类 --> <context:include-filter type="assignable" expression="com.dudu.beans.dao.UserDao"/> </context:component-scan>可以放在属性上
@Controller public class UserController { @Autowired//自动装配具有兼容类型的单个Bean属性 private UserService userService; public void execute() { System.out.println("UserController execute..."); userService.saveUser(); } }也可以放在方法上
@Controller public class UserController { private UserService userService; @Autowired public void setUserService(UserService userService) { this.userService = userService; } public void execute() { System.out.println("UserController execute..."); userService.saveUser(); } }如果需要自动装配的Bean不存在,那么程序会抛出异常,可以使用required = false来解决,此时对应的属性为null
@Repository(value = "userDao") public class UserDaoImpl implements UserDao { @Autowired(required = false) private Car car; @Override public void saveUser() { System.out.println("UserDao saveUser..."); System.out.println("car: " + car); } }如果匹配到了两个同类型的Bean,Spring首先会根据id进行装配,即与属性名称相同的Bean会被装配
@Repository(value = "userDao") public class UserDaoImpl implements UserDao { @Override public void saveUser() { System.out.println("UserDaoImpl saveUser..."); } } @Repository(value = "userDao0") public class UserDaoImpl0 implements UserDao { @Override public void saveUser() { System.out.println("UserDaoImpl0 saveUser..."); } }此时按照id,被装配的是userDao这个Bean
@Service(value = "userService") public class UserServiceImpl implements UserService { private UserDao userDao; @Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void saveUser() { System.out.println("UserServiceImpl saveUser..."); userDao.saveUser(); } }也可以指定要装配的Bean(@Qualifier) 此时被装配的是userDao0这个Bean,该注解放在方法上或者属性上,效果一样
@Service(value = "userService") public class UserServiceImpl implements UserService { private UserDao userDao; @Autowired public void setUserDao(@Qualifier("userDao0") UserDao userDao) { this.userDao = userDao; } @Override public void saveUser() { System.out.println("UserServiceImpl saveUser..."); userDao.saveUser(); } }@Autowired和@Qualifier两个注解结合(@Resource)
@Service(value = "userService") public class UserServiceImpl implements UserService { private UserDao userDao; @Resource(name = "userDao0") public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void saveUser() { System.out.println("UserServiceImpl saveUser..."); userDao.saveUser(); } }可以注入基本类型和String类型的数据(@Value注解) 此时可以使用SPEL表达式
@Component public class Car { @Value("#{'BMW'}") private String brand; }用于改变作用范围的注解(@Scope)
@Component @Scope(value = "singleton") public class Car { private String brand; }和生命周期相关的注解(@PostConstruct,@PreDestroy)
@Service("userService") public class UserServiceImpl implements UserService { @PostConstruct public void init() { System.out.println("init..."); } @PreDestroy public void destory() { System.out.println("destroy..."); } }