zoukankan      html  css  js  c++  java
  • Spring Enable annotation – writing a custom Enable annotation

    原文地址: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.

  • 相关阅读:
    (转)IntelliJ IDEA 插件 阿里巴巴Java开发手册(Alibaba Java Coding Guidelines)
    idea快捷键整理
    (转)mysql使用Navicat 导出和导入数据库
    (转)Intellij Idea工具栏添加打开选中文件的资源管理器位置
    Intellij IDEA设置类注释和方法注释
    mavn jar包依赖冲突解决
    我的Keras使用总结(3)——利用bottleneck features进行微调预训练模型VGG16
    我的Keras使用总结(2)——构建图像分类模型(针对小数据集)
    我的Keras使用总结(1)——Keras概述与常见问题整理
    数据竞赛实战(5)——方圆之外
  • 原文地址:https://www.cnblogs.com/davidwang456/p/6245751.html
Copyright © 2011-2022 走看看