介绍和使用
为什么使用需要使用注解的形式,因为使用xml文件后期可能会出现过于庞大,不利于后期维护
而使用注解可以避免出现这个问题
提示:4.0后推荐注解不推荐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 https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 启动注解扫描 -->
<context:component-scan base-package="项目包"/>
</beans>
Bean装配注解
@Component(3.2之后不推荐)
注解用于标识当前类为Bean以便于交给 IoC
容器 扫描并管理。
通过 value 属性来指定 Bean 的 id,如果不指定 value ,默认的 id 就是当前类名并将首字母改成小写(例如:userDaoImpl)
@Component("userDao")
@Slf4j
public class UserDaoImpl implements UserDao {
@Override
public void add() {
log.debug("UserDaoImpl");
}
}
推荐扫描
@Controller
控制层专属注解,取代 @Component
@Service
业务层专属注解,取代 @Component
@Repository
持久层(dao)专属注解,取代 @Component
注入注解
三种依赖注入的注解:@Autowired
、@Resource
、@Inject
注入查找Bean的介绍
当只有一个实现类是可以根据类型查找,如果有多个实现类就会根据参数名称(在没有指定Bean[包括优先标识]的情况下)查找,如果没有就会报错
@Autowired(spring官方注解)
适用范围(推荐顺序):构造方法(首选) > set方法 > 字段(破坏封装)
不建议使用字段注入,因为会使用反射破坏封装(打开访问权限)
接口只有一个实现类默认是类型注入,同时如果有多个实现类时根据注入方法的形参(参数)名称找到对应的 Bean 的 id,找不到就报错
@Component("userService")
public class UserServiceImpl implements UserService {
// @Autowired 不建议使用字段注入
private UserDao userDao;
// 可以通过构造方法来注入
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
// 可以通过set方法来注入
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
Spring 4.2新特性
如果使用构造方法注入,可以不需要任何的注入注解,默认就按照类型注入
@Qualifier(spring官方注解)
来指定对应的 Bean 的 id,但是只能在普通(set)方法上使用
@Autowired
@Qualifier("userDaoFImpl")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Primary
优先注入标识,多个实现类并且Spring容器不知道注入哪个的情况下生效,在哪个实现类上就优先注入哪个
@Repository
@Primary
@Slf4j
public class UserDaoFImpl implements UserDao {
@Override
public void add() {
log.debug("UserDaoFImpl");
}
}
@Resource(JSR250(Java规范提案))
使用 JSR250(Java规范提案),它设计了 @Resource
注解来支持依赖注入
适用范围(推荐顺序): set方法 > 字段(破坏封装)
Spring 对这个注解也实现了支持,需要注意的是这个注解只能用在字段或者普通的 set 方法上,并不支持构造方法注入,默认也是按照类型注入。
@Resource(name = "bean的id")
public void setUserService(UserService userService) {
this.userService = userService;
}
@Inject(JSR330)
使用 JSR330 标准提供的 @Inject
注解实现依赖注入
但是这个注解并不存在 JDK
中,需要额外添加依赖
适用范围(推荐顺序):构造方法(首选) > set方法 > 字段(破坏封装)
使用方法和@Autowired一样,无非是有多个实现类的情况下需要使用 @Primary
(优先标识符) 或者 @Named
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
@Named(JSR330)
来指定对应的 Bean 的 id,同时也可以用于 Bean 装配
@Inject
@Named("bean的id")
public void setUserService(UserService userService) {
this.userService = userService;
}
Bean 的扩展
@RequiredArgsConstructor
@RequiredArgsConstructor
lombok 迎合了 spring4.2 的新特性实现了更加简洁的注入方法
使用 @RequiredArgsConstructor
注解,lombok 会自动添加
一个带参的构造方法实现构造器的注入,注意:此时的字段必须使用 final 修饰
@Service("userService")
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private UserDao userDao;
@Override
public void add() {
userDao.add();
}
}
@Scope注解
用于设置Bean的作用域,等效于xml中的scope属性
当不指定value属性时,默认是单例,如果要使用原型
就必须指定为prototype
设置proxyMode属性,这个属性就是代理作用域设置
@Scope(value = "prototype",proxyMode = ScopedProxyMode.TARGET_CLASS)