原文地址:https://www.javacodegeeks.com/2015/04/spring-enable-annotation-writing-a-custom-enable-annotation.html

Spring provides a range of annotations with names starting with Enable*, these annotations in essence enable certain Spring managed features to be activated. One good example of such an annotation is EnableWebMvcwhich brings in all the beans needed to support a MVC flow in Spring based applications. Another good example is the EnableAsync annotation to activate beans to support async functionality in Spring based applications.

I was curious about how such annotations work and wanted to document my understanding. The way these annotations are supported can be considered part of the SPI and so may break if the internal implementation changes in future.

Simple Enable* Annotations

One way to think about these custom annotations is that they add a set of new beans into the Spring’s application context. Let us start by defining one such custom annotation:

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target(ElementType.TYPE)
3 @interface EnableSomeBeans {}

and apply this annotation on a Spring @Configuration class:

1 @Configuration
2 @EnableSomeBeans
3 public static class SpringConfig {}

So now to bring in a set of beans when this annotation is applied is as simple as adding the set of beans to bring in using @Import annotation this way:

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target(ElementType.TYPE)
3 @Import(SomeBeanConfiguration.class)
4 @interface EnableSomeBeans {}

That is essentially it, if this imported @Configuration class defines any beans, they would now be part of the Application context:

01 @Configuration
02 class SomeBeanConfiguration {
03  
04     @Bean
05     public String aBean1() {
06         return "aBean1";
07     }
08  
09     @Bean
10     public String aBean2() {
11         return "aBean2";
12     }
13 }

Here is a gist with a working sample.

Enable* Annotations with Selectors

Enable annotations can be far more complex though, they can activate a different family of beans based on the context around them. An example of such an annotation is EnableCaching which activates configuration based on different caching implementations available in the classpath.

Writing such Enable* annotations is a little more involved than the simpler example earlier. As before start with a custom annotation:

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target(ElementType.TYPE)
3 @Import(SomeBeanConfigurationSelector.class)
4 public @interface EnableSomeBeansSelector {
5     String criteria() default "default";
6 }

Note that in this case the custom annotation has a sample field called criteria, what I want to do is to activate two different set of beans based on this criteria. This can be achieved using a @Configuration selector which can return different @Configuration file based on the context(in this instance the value of the criteria field). This selector has a simple signature and this is a sample implementation:

01 import org.springframework.context.annotation.ImportSelector;
02 import org.springframework.core.annotation.AnnotationAttributes;
03 import org.springframework.core.type.AnnotationMetadata;
04  
05 public class SomeBeanConfigurationSelector implements ImportSelector {
06     @Override
07     public String[] selectImports(AnnotationMetadata importingClassMetadata) {
08         AnnotationAttributes attributes =
09                 AnnotationAttributes.fromMap(
10                         importingClassMetadata.getAnnotationAttributes
11 (EnableSomeBeansSelector.class.getName(), false));
12         String criteria = attributes.getString("criteria");
13         if (criteria.equals("default")) {
14             return new String[]{"enableannot.selector.SomeBeanConfigurationDefault"};
15         }else {
16             return new String[]{"enableannot.selector.SomeBeanConfigurationType1"};
17         }
18     }
19 }
20  
21 @Configuration
22 class SomeBeanConfigurationType1 {
23  
24     @Bean
25     public String aBean() {
26         return "Type1";
27     }
28  
29 }
30  
31 @Configuration
32 class SomeBeanConfigurationDefault {
33  
34     @Bean
35     public String aBean() {
36         return "Default";
37     }
38  
39 }

So if the criteria field is “default”, the beans in “SomeBeanConfigurationDefault” gets added in, else the one in “SomeBeanConfigurationType1”

  • Here is a gist with a working sample.

Conclusion

I hope this gives an appreciation for how Spring internally implements the @Enable* annotations, as an application developer you may not need to create such annotations yourself, a simpler mechanism will be to use @Configuration classes and Spring bean profiles to compose applications.

转载于:https://www.cnblogs.com/davidwang456/p/6245751.html

Spring Enable annotation – writing a custom Enable annotation相关推荐

  1. Spring Enable批注–编写自定义的Enable批注

    Spring提供了一系列名称以Enable *开头的注释,这些注释本质上使某些Spring管理的功能可以被激活. 这样的注释的一个很好的例子是EnableWebMvc ,它引入了在基于Spring的应 ...

  2. 注解类型异常:@ComponentScan ANNOTATION type filter requires an annotation typ

    遇到bug是这样的: Caused by: java.lang.IllegalArgumentException: @ComponentScan ANNOTATION type filter requ ...

  3. java annotation list_[Java5新特性]Annotation注解

    Annotation概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annotation就是提供了一种为程序元素设置元数据的方法 ...

  4. java annotation详解_Java注解Annotation详解

    从JDK5开始,Java增加了Annotation(注解),Annotation是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行相应的处理.通过使用Annotation,开发人员可 ...

  5. Spring的Autowired自动装配(XML版本+Annotation版本+源码+解析)

    http://moshowgame.iteye.com/blog/1607718 @Autowired自动装配 上面的例子我们用的都是手动装配的,如果DAO-Service一多那就很麻烦了,那么我们需 ...

  6. 【Spring第六篇】注解:Annotation

    注解:Annotation 首先不惜在spring容器配置中加上以下字段: <?xml version="1.0" encoding="UTF-8"?&g ...

  7. Java Spring源代码学习之How is class annotation evaluated by Spring framework

    Created by Wang, Jerry, last modified on Aug 12, 2016

  8. Quan Xidorn: Writing A Custom Derive From Zero

    作者是Mozilla贡献者,stylo(firefox新版css解析渲染器)主要开发维护者. Slide 很棒.以下是部分现场内容.

  9. Spring Enable 是什么?

    本文内容如有错误.不足之处,欢迎技术爱好者们一同探讨,在本文下面讨论区留言,感谢. 文章目录 简述 分类 核心类 实现 原理 @Import 的作用 @Configuration和@Import @E ...

最新文章

  1. 使用 sched_setaffinity 将线程绑到CPU核上运行
  2. 【BZOJ】P2144 跳跳棋
  3. 用MATLAB实现神经网络
  4. java 数组转字符串 字符串转数组,java高级面试笔试题
  5. Could not load file or assembly An attempt was made to load a program with an incorrect format.
  6. 做企业需要一点逆向思维
  7. 三大框架ssh整合(一)
  8. 怎样找到一份深度学习的工作(附学习材料,资源与建议)
  9. c语言从入门到精通真垃圾,从入门到精通的C语言(吐血量)
  10. 三宝小精灵机器人_“三宝”机器人
  11. 多模态知识图谱构建和推理技术 王萌 东南大学
  12. mybatis之 trim prefix=( suffix=)
  13. Android蓝牙4.0单车锁应用实例开发
  14. c语言数独出题程序,C语言实现的数独解题程序
  15. android 前后同时预览_GitHub 上优质项目整理,不只 Android
  16. c语言中方阵对角线的和程序,c语言程序 1、方阵求出主对角线上元素之和;2、辅对角线上元素之积;3方阵中最大的元素...
  17. ppt怎么把图片做成翻书效果_ppt怎么做出翻页效果图文教程
  18. 推特 我们目前不能注册此邮箱地址_英雄联盟手游来了!最简单的下载/安装/注册教程!...
  19. php 刀客友朋,说好的英雄拯救世界
  20. 【⏰亲】今天冬至,早些回家!

热门文章

  1. oracle命令报01034,ORA-01034错误的解决办法-数据库专栏,ORACLE
  2. linux comm 12,Linux comm命令
  3. authenticationstring mysql_mysql5.7修改密码password字段变成了authentication_string字段
  4. socket同步和异步通信区别_程序员必知必会,同步通信与异步通信,你了解多少...
  5. win服务器自动发邮件,windows关机前执行脚本设置与关机blat自动发送邮件脚本模板...
  6. oracle远程连接串,oracle远程连接
  7. php自动生成新闻页,自动发布新闻页面的php代码
  8. arm-linux-g 找不到头文件,交叉编译错误“ arm-none-eabi-g ++找不到条目符号”
  9. Second Week: Git与Github的使用
  10. linux中的nm命令