Spring 注解使用和分类

Spring 注解使用和分类

介绍和使用

为什么使用需要使用注解的形式,因为使用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)