Spring Enable* 注解

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

posted @ 2018-11-06 16:07  软件匠工  阅读(2401)  评论(0编辑  收藏  举报