经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
一文带你了解 Spring 的@Enablexxx 注解 - zi-you
来源:cnblogs  作者:zi-you  时间:2022/11/28 8:58:16  对本文有异议
  1. layout: post
  2. categories: Java
  3. title: 一文带你了解 Spring @Enablexxx 注解
  4. tagline: by 子悠
  5. tags:
  6. - 子悠

前面的文章给大家介绍 Spring 的重试机制的时候有提到过 Spring 有很多 @Enable 开头的注解,平时在使用的时候也没有注意过为什么会有这些注解,今天就给大家介绍一下。

@Enable 注解

首先我们先看一下有哪些常用的 @Enable 开头的注解,以及都是干什么用的。

  • @EnableRetry:开启 Spring 的重试功能;
  • @EnableScheduling:开启 Spring 的定时功能;
  • @EnableAsync:开启 Spring 的异步功能;
  • @EnableAutoConfiguration:开启 Spring 的自动装配功能;

上面这几个是我们经常会用到和看到的,都知道在使用相应的功能的时候,如果没有配置上面的注解功能都是不生效的。以我们前面的文章的 Spring 重试为例,我们需要在启动类上面配置 @EnableRetry ,否则自动重试注解 @Retryable 是不会生效的,如下所示,没看过的可以去看下,https://mp.weixin.qq.com/s/U_nm92ujCGArkii5ze7uaA。

@Import 注解

那有的小伙伴就要问了,这个 @EnableRetry 注解到底有什么作用呢?不用这个注解就没办法了吗?

要知道这个注解有什么功效,我们可以点开看看源码,代码如下

  1. package org.springframework.retry.annotation;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. import org.springframework.context.annotation.EnableAspectJAutoProxy;
  8. import org.springframework.context.annotation.Import;
  9. @Target(ElementType.TYPE)
  10. @Retention(RetentionPolicy.RUNTIME)
  11. @EnableAspectJAutoProxy(proxyTargetClass = false)
  12. @Import(RetryConfiguration.class)
  13. @Documented
  14. public @interface EnableRetry {
  15. boolean proxyTargetClass() default false;
  16. }

可以看到源码很简单,其中最有用的就一行 @Import(RetryConfiguration.class) ,我们可以尝试把这一行代码放到启动类上面看看效果,如下所示,可以看到项目可以正常启动,并且也还是有效果的,说明跟我们的 @EnableRetry 注解是一样的。

从上面的实验效果我们可以看到 @EnableRetry 注解其实就是对 @Import(RetryConfiguration.class) 的一个封装,同样的通过源码我们还可以看到 @EnableScheduling 注解就是对 @Import({SchedulingConfiguration.class}) 的一个封装。

  1. @Target({ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Import({SchedulingConfiguration.class})
  4. @Documented
  5. public @interface EnableScheduling {
  6. }

那如果在没有 @Enablexxx 注解的时候,我们直接通过 @Import 注解是可以这样写的,在一个 @Import 注解里面包含多个配置类,不过这种在配置类较多的场景下还是相对不够简洁的,因而才有了各自功能对应的 @Enable 注解。

  1. package com.example.demo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.context.annotation.ComponentScan;
  5. import org.springframework.context.annotation.Import;
  6. import org.springframework.retry.annotation.RetryConfiguration;
  7. import org.springframework.scheduling.annotation.SchedulingConfiguration;
  8. @SpringBootApplication
  9. @ComponentScan(value = "com.example.demo.*")
  10. @Import({RetryConfiguration.class, SchedulingConfiguration.class})
  11. public class DemoApplication {
  12. public static void main(String[] args) {
  13. SpringApplication.run(DemoApplication.class, args);
  14. }
  15. }

为什么要使用 @Import 注解呢

那么很多的小伙伴又要问了,为啥要通过使用 @Import 注解将配置类加载进来呢?在项目中的 Spring 上下文中不是能直接获取到吗?为此我们来实验一下,通过下面的代码我们看下是否能在 Spring 的容器中获取到 RetryConfiguration Bean

  1. package com.example.demo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.context.ConfigurableApplicationContext;
  5. import org.springframework.context.annotation.ComponentScan;
  6. import org.springframework.context.annotation.Import;
  7. import org.springframework.retry.annotation.RetryConfiguration;
  8. import org.springframework.scheduling.annotation.SchedulingConfiguration;
  9. @SpringBootApplication
  10. @ComponentScan(value = "com.example.demo.*")
  11. //@Import({RetryConfiguration.class, SchedulingConfiguration.class})
  12. public class DemoApplication {
  13. public static void main(String[] args) {
  14. ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
  15. Object bean = applicationContext.getBean("org.springframework.retry.annotation.RetryConfiguration");
  16. System.out.println(bean.toString());
  17. }
  18. }

启动过后我们可以看到结果如下,提示我们在容器中找不到这个 bean,有点小伙伴会说是不是 bean 的名字写错了,其实并不是,紧接着我们再把注释的那一行放开再运行一下。

可以看到,这次我们成功的获取到了这个 Bean,这个实验就是告诉我们,其实在默认情况下,Spring 的容器中是找不到RetryConfiguration 这个 Bean 的,因此我们需要通过使用 @Import 注解,将该类加载到容器中。

那么为什么在容器中找不到这个 Bean 呢?

其实很简单,因为这个 Bean 跟我们当前环境的类是不是同一个包里面的,在项目启动的过程中并不会扫描到 RetryConfiguration 类所在的包,因此找不到是很正常的。

总结

上面通过 @EnableRetry 这个注解带大家了解了一下 Spring@Enable 开头的注解的使用原理,相信大家对这些注解有了更深入的了解。简单来说就是因为我们要使用的很多类并不在我们项目所在的包下面,我们不能将所有的依赖包都进行扫描,也不不方便将所有的配置类都通过 @Import 的方式进行导入,而是让每个功能的项目包都提供一个 @Enable 开头的注解,我们直接启用注解就可以达到效果。

这种方式我们在平时的开发中也可以自己实现,实现一个自己的 @Enable 开头的注解来实现特定的功能,下一篇文章我们来带大家实现一下。好了,今天的文章就到这里,如果觉得有帮助还请大家帮我们的文章点赞,评论,转发,一键三连走起。


更多优质内容欢迎关注公众号【Java 极客技术】,我准备了一份面试资料,回复【bbbb07】免费领取。希望能在这寒冷的日子里,帮助到大家。

原文链接:https://www.cnblogs.com/zi-you/p/16920365.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号