Spring提供了一系列以Enable开头的注解,这些注解本质上是激活Spring的某些管理功能。比如,EnableWebMvc。 这个注解引入了MVC框架在Spring 应用中需要用到的所有bean。另外一个注解式EnableAsync, 它让Bean在spring 应用中支持异步功能。

我很好奇这些注解是怎样工作的,并把我的理解写下来。这些注解的工作原理可以理解为SPI的一部分,如果将来实现有变化可以切换。

简单的Enable*注解

我们可以把这些简单的注解理解为为spring 上下文引入一组bean。 我们开始来定义一些这样的注解:

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

并把这个注解应用到spring 配置类上:

@Configuration
@EnableSomeBeans
public static class SpringConfig {}

如果希望引入一组新的bean, 只需要简单的使用@Import注解,如下:

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

如果被引入的@Configuration定义了Bean, 那么这么bean就会被引入到spring 上下文。

@Configuration
class SomeBeanConfiguration { @Bean
public String aBean1() {
return "aBean1";
} @Bean
public String aBean2() {
return "aBean2";
}
}

完整代码可以从这里下载:https://gist.github.com/bijukunjummen/847456b55ae2340fff65

带Selector的Enable注解

当然,Enable注解可以更加复杂,可以根据所在上下文来激活不同类型的bean。比如:EnableCaching,可以根据类路径上的不同实现来激活对应的缓存。

这样的注解比前面的例子复杂些:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfigurationSelector.class)
public @interface EnableSomeBeansSelector {
String criteria() default "default";
}

上面的注解有一个叫criteria的属性,我想根据这个属性来激活不同的bean。这可以通过定义一个@Configuration Selector返回不同的@Configuration来实现。样板代码如下:

mport org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata; public class SomeBeanConfigurationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
AnnotationAttributes attributes =
AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableSomeBeansSelector.class.getName(), false));
String criteria = attributes.getString("criteria");
if (criteria.equals("default")) {
return new String[]{"enableannot.selector.SomeBeanConfigurationDefault"};
}else {
return new String[]{"enableannot.selector.SomeBeanConfigurationType1"};
}
}
} @Configuration
class SomeBeanConfigurationType1 { @Bean
public String aBean() {
return "Type1";
} } @Configuration
class SomeBeanConfigurationDefault { @Bean
public String aBean() {
return "Default";
} }

所以,如果criteria是detaul, SomeBeanConfigurationDefault被加入,反之,加入SomeBeanConfigurationType1。

原文地址:http://www.java-allandsundry.com/2015/04/spring-enable-annotation-writing-custom.html

Spring Enable* 注解的更多相关文章

  1. Spring 3.1新特性之二:@Enable*注解的源码,spring源码分析之定时任务Scheduled注解

    分析SpringBoot的自动化配置原理的时候,可以观察下这些@Enable*注解的源码,可以发现所有的注解都有一个@Import注解.@Import注解是用来导入配置类的,这也就是说这些自动开启的实 ...

  2. Spring高级话题-@Enable***注解的工作原理

    出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解 激活Aspect自动代理 & ...

  3. Spring Boot @Enable*注解源码解析及自定义@Enable*

      Spring Boot 一个重要的特点就是自动配置,约定大于配置,几乎所有组件使用其本身约定好的默认配置就可以使用,大大减轻配置的麻烦.其实现自动配置一个方式就是使用@Enable*注解,见其名知 ...

  4. Spring中的@Enable注解

    本文转载自SpringBoot中神奇的@Enable注解? 导语 在SpringBoot开发过程,我们经常会遇到@Enable开始的好多注解,比如@EnableEurekaServer.@Enable ...

  5. Spring高级特性之三:@Enable*注解的工作原理

    Spring Boot中阐述热插拔技术的时候,简单地提及@Enable*注解.随着多种框架的应用及深入了解,@Enable*这个注解在各种框架中应用相当普及. 那么@Enable*注解工作原理是怎么样 ...

  6. Spring的@Enable*注解的工作原理

    转自:https://blog.csdn.net/chengqiuming/article/details/81586948 一 列举几个@Enable*注解的功能 @EnableAspectJAut ...

  7. Java 必须掌握的 20+ 种 Spring 常用注解

    Spring部分 1.声明bean的注解 @Component 组件,没有明确的角色 @Service 在业务逻辑层使用(service层) @Repository 在数据访问层使用(dao层) @C ...

  8. [No0000174]Spring常用注解(收藏大全)

    Spring部分 1.声明bean的注解 @Component 组件,没有明确的角色 @Service 在业务逻辑层使用(service层) @Repository 在数据访问层使用(dao层) @C ...

  9. 【面试篇】必须掌握的Spring 常用注解

    注解本身没有功能的,就和 xml 一样.注解和 xml 都是一种元数据,元数据即解释数据的数据,这就是所谓配置. 本文主要罗列 Spring|Spring MVC相关注解的简介. Spring部分 1 ...

随机推荐

  1. 自己定义ViewGroup实现仿淘宝的商品详情页

    近期公司在新版本号上有一个须要. 要在首页加入一个滑动效果, 详细就是仿照X宝的商品详情页, 拉到页面底部时有一个粘滞效果, 例如以下图 X东的商品详情页,假设用户继续向上拉的话就进入商品图文描写叙述 ...

  2. mysql5.6 sql_mode设置为宽松模式

    最近遇到一个很奇怪的事情 由于数据人员的需求,现在需要修改mysql的sql_mode sql_mode默认是sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_ ...

  3. IoC之AutoFac(一)——简单使用和组件注册

    阅读目录 一.AutoFac简单使用 二.注册 2.1 注册方式 2.2 带参数注册 回到顶部 一.AutoFac简单使用 1 namespace AutofacDemo 2 { 3 class Pr ...

  4. 网络协议学习(2)---IP地址

    一.IPv4地址 IPv4地址为32bit地址,分为5类(ABCDE,这里不讨论特殊用途的D和E类). 通常我们八位一看,写成4个部分,例如:00000000 00000000 00000000 00 ...

  5. 用virsh console vhosts 卡住

    [root@666 ok]# virsh list --all Id Name State ---------------------------------------------------- 1 ...

  6. golang中值类型/指针类型的变量区别总结

    转自:https://segmentfault.com/a/1190000012329213 值类型的变量和指针类型的变量 先声明一个结构体: type T struct { Name string ...

  7. sqoop导入数据到hive中元数据问题

    简单配置了sqoop之后开始使用,之前用的时候很好用,也不记得有没有启动hivemetastore,今天用的时候没有启动,结果导入数据时,如果使用了db.tablename,就会出现找不到数据库的错, ...

  8. Odoo 进销存报表现已开源

    根据会计区间或自定义查询时间段,对仓库的产品出入库情况进行查看: 模块地址参见内部群公告.

  9. php 慢配置文件

    [root@localhost etc]# cat php-fpm.conf[global]pid = /usr/local/php/var/run/php-fpm.piderror_log = /u ...

  10. Python中的retry

    1.通过语言特性实现: for i in range(0,100): while True: try: # do stuff except SomeSpecificException: continu ...