0%

spring注解整理

Spring 核心注解全解析:从配置到实战

Spring 框架的注解体系是简化开发、实现 “约定优于配置” 的核心。从早期的 XML 配置到现在的全注解开发,注解极大地提升了开发效率。本文将系统整理 Spring 常用注解,按功能分类详解其作用、用法及适用场景,帮助开发者快速掌握注解的使用技巧。

配置类与 Bean 定义注解

这类注解用于替代 XML 配置文件,实现 Bean 的定义与配置类的声明,是注解开发的基础。

1. @Configuration

  • 作用:标记类为 Spring 配置类,相当于 XML 配置中的 <beans> 标签。

  • 特点:配置类中可通过 @Bean 定义 Bean,容器启动时会扫描并加载这些配置。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    @Configuration // 声明为配置类
    public class AppConfig {
    // 定义 Bean(方法名默认作为 Bean 的 id)
    @Bean
    public UserService userService() {
    return new UserService();
    }
    }

2. @Bean

  • 作用:在配置类中定义 Bean,相当于 XML 中的 <bean> 标签。

  • 核心属性:

    • name/value:指定 Bean 的 id(默认是方法名);
    • initMethod:Bean 初始化方法(相当于 XML 的 init-method);
    • destroyMethod:Bean 销毁方法(相当于 XML 的 destroy-method)。
  • 示例:

    1
    2
    3
    4
    @Bean(name = "userDao", initMethod = "init", destroyMethod = "destroy")
    public UserDao userDao() {
    return new UserDao();
    }

3. @Scope

  • 作用:指定 Bean 的作用域(生命周期范围)。

  • 常用值:

    • singleton(默认):单例,容器中只有一个实例,随容器启动创建;
    • prototype:原型,每次获取时创建新实例;
    • request:Web 环境中,每个请求对应一个实例;
    • session:Web 环境中,每个会话对应一个实例。
  • 示例:

    1
    2
    3
    4
    5
    @Bean
    @Scope("prototype") // 原型模式,每次获取创建新对象
    public User user() {
    return new User();
    }

4. @Lazy

  • 作用:延迟加载单例 Bean(默认单例 Bean 随容器启动创建)。

  • 适用场景:Bean 初始化耗时较长(如加载大量数据),希望首次使用时再创建。

  • 示例:

    1
    2
    3
    4
    5
    @Bean
    @Lazy // 单例 Bean 首次使用时才初始化
    public CacheService cacheService() {
    return new CacheService();
    }

5. @Conditional

  • 作用:根据条件动态注册 Bean(Spring 4+ 新增)。

  • 用法:配合 Condition 接口,实现条件判断逻辑。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 自定义条件:仅当系统为 Windows 时注册 Bean
    public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    return context.getEnvironment().getProperty("os.name").contains("Windows");
    }
    }

    @Configuration
    public class SystemConfig {
    @Bean
    @Conditional(WindowsCondition.class) // 满足 Windows 条件才注册
    public SystemService windowsService() {
    return new WindowsService();
    }
    }

6. @Primary

  • 作用:当存在多个同类型 Bean 时,指定默认被注入的 Bean。

  • 解决问题:避免 @Autowired 因类型匹配多个 Bean 而抛出异常。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Bean
    @Primary // 默认注入该数据源
    public DataSource primaryDataSource() {
    return new DruidDataSource();
    }

    @Bean
    public DataSource secondaryDataSource() {
    return new HikariDataSource();
    }

    // 注入时会自动选择 primaryDataSource
    @Autowired
    private DataSource dataSource;

7. FactoryBean(接口,非注解)

  • 作用:通过工厂模式创建复杂 Bean(间接定义 Bean 的一种方式)。

  • 特点getObject() 返回实际 Bean 实例,getObjectType() 指定类型。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // 定义工厂 Bean
    public class UserFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
    User user = new User();
    user.setName("工厂创建的用户");
    return user;
    }

    @Override
    public Class<?> getObjectType() {
    return User.class;
    }
    }

    // 配置类中注册工厂 Bean
    @Configuration
    public class FactoryConfig {
    @Bean
    public UserFactoryBean userFactoryBean() {
    return new UserFactoryBean();
    }
    }

    // 获取时,默认返回 User 实例(非工厂本身)
    User user = context.getBean(User.class);
    // 获取工厂本身需加 & 前缀
    UserFactoryBean factory = context.getBean("&userFactoryBean", UserFactoryBean.class);

组件扫描与导入注解

这类注解用于自动扫描组件或导入外部配置,简化 Bean 的注册流程。

1. @ComponentScan

  • 作用:自动扫描指定包下的组件(标注 @Component@Controller@Service@Repository 的类),相当于 XML 的 <context:component-scan>

  • 核心属性:

    • basePackages:指定扫描的包路径;
    • includeFilters:指定需要包含的组件(需配合 useDefaultFilters = false);
    • excludeFilters:指定需要排除的组件。
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Configuration
    // 扫描 com.example 包,排除 @Controller 组件
    @ComponentScan(
    basePackages = "com.example",
    excludeFilters = @ComponentScan.Filter(
    type = FilterType.ANNOTATION,
    classes = Controller.class
    )
    )
    public class ScanConfig {
    }

2. @Import

  • 作用:导入外部组件到容器中,相当于 XML 的 <import>

  • 三种用法:

    1. 直接导入类:Bean 的 id 为全类名;
    2. 通过 ImportSelector 接口:动态返回需要导入的类名数组;
    3. 通过 ImportBeanDefinitionRegistrar 接口:手动注册 Bean 到容器。
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 1. 直接导入类
    @Configuration
    @Import({User.class, Role.class}) // 导入 User 和 Role 作为 Bean
    public class ImportConfig {
    }

    // 2. 通过 ImportSelector
    public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
    return new String[]{"com.example.Permission"}; // 返回需要导入的类
    }
    }
    @Configuration
    @Import(MyImportSelector.class) // 导入 Selector 指定的类
    public class ImportSelectorConfig {
    }

3. @ImportResource

  • 作用:导入 XML 配置文件,实现注解与 XML 配置的混合使用。

  • 适用场景:遗留项目中存在 XML 配置,需在注解配置中复用。

  • 示例:

    1
    2
    3
    4
    @Configuration
    @ImportResource("classpath:applicationContext.xml") // 导入 XML 配置
    public class MixedConfig {
    }

依赖注入与装配注解

这类注解用于实现 Bean 之间的依赖注入,替代 XML 中的 <property><constructor-arg>

1. @Autowired

  • 作用:自动按类型注入依赖(默认要求依赖必须存在)。

  • 特点:

    • 可标注在字段、构造方法、setter 方法上;
    • 结合 @Qualifier 可按名称注入;
    • required = false 允许依赖为 null。
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Service
    public class UserService {
    // 字段注入
    @Autowired
    @Qualifier("userDao") // 指定注入 id 为 userDao 的 Bean
    private UserDao userDao;

    // 构造方法注入(推荐,便于测试)
    @Autowired
    public UserService(RoleService roleService) {
    this.roleService = roleService;
    }

    // setter 方法注入
    @Autowired(required = false) // 允许为 null
    public void setLogService(LogService logService) {
    this.logService = logService;
    }
    }

2. @Resource(JSR-250 规范)

  • 作用:类似 @Autowired,但默认按名称注入(兼容 Spring)。

  • 与 @Autowired 区别:

    • @Autowired 是 Spring 注解,@Resource 是 Java 规范注解;
    • @Resource 可通过 name 属性指定 Bean 名称,@Autowired 需配合 @Qualifier
  • 示例:

    1
    2
    3
    4
    5
    @Service
    public class OrderService {
    @Resource(name = "orderDao") // 按名称注入 orderDao
    private OrderDao orderDao;
    }

3. @Qualifier

  • 作用:配合 @Autowired 按名称注入 Bean,解决同类型多个 Bean 的冲突。
  • 示例:见 @Autowired 的用法。

4. @Required(较少使用)

  • 作用:标注在 setter 方法上,要求该属性必须在配置中被赋值(否则启动报错)。
  • 注意:Spring 5+ 已废弃,推荐使用构造方法注入替代。

5. @DependsOn

  • 作用:强制指定 Bean 的加载顺序,确保依赖的 Bean 先初始化。

  • 适用场景:Bean A 依赖 Bean B 的初始化逻辑(如静态资源加载)。

  • 示例:

    1
    2
    3
    4
    5
    @Service
    @DependsOn("cacheService") // 确保 cacheService 先加载
    public class UserService {
    // 依赖 cacheService 的初始化结果
    }

属性赋值与配置注解

这类注解用于为 Bean 的属性赋值,尤其是读取外部配置文件中的值。

1. @Value

  • 作用:为属性赋值,支持三种类型的值:

    • 字面量(如字符串、数字);
    • SpEL 表达式(#{});
    • 外部配置文件中的值(${})。
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Component
    public class AppConfig {
    @Value("默认名称") // 字面量
    private String appName;

    @Value("#{T(java.lang.Math).random() * 100}") // SpEL 表达式(随机数)
    private double randomValue;

    @Value("${server.port}") // 外部配置文件中的值
    private int port;
    }

2. @PropertySource

  • 作用:加载外部 properties 配置文件,配合 @Value 读取配置。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Configuration
    @PropertySource("classpath:app.properties") // 加载类路径下的配置文件
    public class PropertyConfig {
    @Bean
    public TestBean testBean() {
    return new TestBean();
    }
    }

    // app.properties 内容:test.name=张三
    public class TestBean {
    @Value("${test.name}") // 读取配置文件中的值
    private String name;
    }

3. @PropertySources

  • 作用:组合多个 @PropertySource,加载多个配置文件。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    @Configuration
    @PropertySources({
    @PropertySource("classpath:db.properties"),
    @PropertySource("classpath:log.properties")
    })
    public class MultiPropertyConfig {
    }

Bean 生命周期注解

这类注解用于定义 Bean 初始化和销毁时的回调逻辑。

1. @PostConstruct(JSR-250 规范)

  • 作用:标注在方法上,该方法在 Bean 构造完成后、初始化前执行(相当于 init-method)。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    @Service
    public class UserService {
    @PostConstruct // 初始化后执行(如加载缓存)
    public void init() {
    System.out.println("UserService 初始化完成");
    }
    }

2. @PreDestroy(JSR-250 规范)

  • 作用:标注在方法上,该方法在 Bean 销毁前执行(相当于 destroy-method)。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    @Service
    public class OrderService {
    @PreDestroy // 销毁前执行(如释放资源)
    public void destroy() {
    System.out.println("OrderService 即将销毁");
    }
    }

环境与 Profile 注解

这类注解用于实现多环境配置(如开发、测试、生产环境的差异化配置)。

1. @Profile

  • 作用:指定 Bean 在特定环境下才会被注册。

  • 使用方式:

    • 标注在类或方法上;
    • 通过 spring.profiles.active 指定当前环境(如 -Dspring.profiles.active=dev)。
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Configuration
    public class DataSourceConfig {
    @Bean
    @Profile("dev") // 开发环境数据源
    public DataSource devDataSource() {
    return new HikariDataSource();
    }

    @Bean
    @Profile("prod") // 生产环境数据源
    public DataSource prodDataSource() {
    return new DruidDataSource();
    }
    }

功能开启注解(@Enable*)

Spring 通过 @Enable* 注解开启特定功能,底层通过 @Import 导入相关配置,简化功能启用流程。

注解 作用 对应 XML 配置
@EnableAspectJAutoProxy 开启 AOP 自动代理(支持 @Aspect <aop:aspectj-autoproxy/>
@EnableTransactionManagement 开启注解式事务(支持 @Transactional <tx:annotation-driven/>
@EnableAsync 开启异步方法支持(支持 @Async -
@EnableScheduling 开启定时任务支持(支持 @Scheduled -
@EnableWebMvc 开启 Spring MVC 配置支持 <mvc:annotation-driven/>
@EnableCaching 开启缓存支持(支持 @Cacheable 等) <cache:annotation-driven/>
  • 示例:开启事务管理

    1
    2
    3
    4
    5
    6
    7
    8
    @Configuration
    @EnableTransactionManagement // 替代 XML 的 <tx:annotation-driven>
    public class TxConfig {
    @Bean
    public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource());
    }
    }

测试相关注解

这类注解用于 Spring 环境下的单元测试,简化测试环境搭建。

1. @RunWith(SpringJUnit4ClassRunner.class)

  • 作用:指定 JUnit 测试的运行器为 Spring 专用运行器,用于加载 Spring 容器。

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @RunWith(SpringJUnit4ClassRunner.class) // 整合 Spring 和 JUnit
    @ContextConfiguration(classes = AppConfig.class)
    public class UserServiceTest {
    @Autowired
    private UserService userService;

    @Test
    public void test() {
    userService.query();
    }
    }

2. @ContextConfiguration

  • 作用:指定测试时加载的 Spring 配置(配置类或 XML 文件)。

  • 示例:

    1
    2
    3
    4
    // 加载配置类
    @ContextConfiguration(classes = {AppConfig.class, DataConfig.class})
    // 或加载 XML 文件
    @ContextConfiguration(locations = "classpath:applicationContext.xml")

总结与最佳实践

  1. 配置类与 Bean 定义:优先使用 @Configuration + @Bean 替代 XML,配合 @Scope@Lazy 控制 Bean 生命周期。
  2. 依赖注入:推荐构造方法注入(便于测试),结合 @Autowired + @Qualifier 解决依赖冲突;@Resource 可作为兼容 Java 规范的替代方案。
  3. 属性赋值@Value + @PropertySource 是读取外部配置的标准方式,Spring Boot 中可配合 @ConfigurationProperties 增强。
  4. 多环境配置@Profile 是实现环境隔离的最佳选择,避免硬编码环境相关配置。
  5. 功能开启@Enable* 注解简化功能启用,无需记忆复杂的 XML 标签

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10