SpringBoot之神秘的注解

本文深入探讨了SpringBoot中的注解使用技巧,包括元注解、组合注解的概念及其实现方式,并介绍了如何通过组合注解简化代码。

title: SpringBoot之神秘的注解 tags:

  • SpringBoot
  • 注解
  • 元注解
  • 组合注解 categories: springboot date: 2017-11-27 23:28:37

背景

  1. 大量的XML让开发者厌恶,因此Spring提供了许多注解来完成各种功能。
  2. 大量的注解让开发者厌恶 ,因此Spring提供了组合注解来完成各种功能。

举例

  1. 最典型的SpringMVC中我们使用如下注解 @Controller
    事实上我们接触到Controller时都会如下说明Controller Service Repository事实上和Component 没有差别 但是Spring后期可能可能条件不同的语义 因此注意使用
        /**
         * Indicates that an annotated class is a "Controller" (e.g. a web controller).
         *
         * <p>This annotation serves as a specialization of {@link Component @Component},
         * allowing for implementation classes to be autodetected through classpath scanning.
         * It is typically used in combination with annotated handler methods based on the
         * {@link org.springframework.web.bind.annotation.RequestMapping} annotation.
         *
         * @author Arjen Poutsma
         * @author Juergen Hoeller
         * @since 2.5
         * @see Component
         * @see org.springframework.web.bind.annotation.RequestMapping
         * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
         */
        @Target({ElementType.TYPE})
        @Retention(RetentionPolicy.RUNTIME)
        @Documented
        @Component
        public @interface Controller {
         
           /**
            * The value may indicate a suggestion for a logical component name,
            * to be turned into a Spring bean in case of an autodetected component.
            * @return the suggested component name, if any
            */
           String value() default "";
         
        }
    
复制代码
 
复制代码
  1. 我们把修饰其他注解的注解称之为Meta Annotation【元注解】
    meta-annotation is an annotation that is declared on another annotation. An annotation is therefore meta-annotated if it is annotated with another annotation. For example, any annotation that is declared to be documented is meta-annotated with @Documented from thejava.lang.annotation package.
  2. 当我们业务越发复杂的情况下我们会大量的使用注解进行组合 比如
        @RestController
        @RequestMapping("user")
        public class TbUserController extends AbstractRestController<TbUserVo, TbUserSo, BigInteger> {
            @Resource
            private TbUserService tbUserService;
         
         
        }
复制代码

这个注解还比较少,但是对于SpringBoot 来说可能注解的量会直线上升,比如

        @AutoConfigurationPackage
        @Import(EnableAutoConfigurationImportSelector.class)
        @EnableAutoConfiguration
        @ComponentScan(excludeFilters = {
              @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
              @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
复制代码

4. 那么由于如上的问题带来了一个问题 可能一个简单的类中的代码比注解还要少! 5. 我们通过组合注解的方式来解决此问题

我们声明如下
复制代码
        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        @Documented
        @Inherited
        @SpringBootConfiguration
        @EnableAutoConfiguration
        @ComponentScan(excludeFilters = {
              @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
              @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
        public @interface SpringBootApplication {
        }
复制代码
 
复制代码

Spring注解编程模型

github.com/spring-proj…

对于Spring来说通常定义的注解是要适配原有的功能 比如Controller注解可以声明Bean的名称

但是一旦定义的组合注解的名称相同自然就会存在如下的问题【覆盖】

Spring提供了AliasFor注解来完成别名的转换 比如

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
          @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
          @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
     
       /**
        * Exclude specific auto-configuration classes such that they will never be applied.
        * @return the classes to exclude
        */
       @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")
       Class<?>[] exclude() default {};
     
       /**
        * Exclude specific auto-configuration class names such that they will never be
        * applied.
        * @return the class names to exclude
        * @since 1.3.0
        */
       @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
       String[] excludeName() default {};
     
       /**
        * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
        * for a type-safe alternative to String-based package names.
        * @return base packages to scan
        * @since 1.3.0
        */
       @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
       String[] scanBasePackages() default {};
     
       /**
        * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
        * scan for annotated components. The package of each class specified will be scanned.
        * <p>
        * Consider creating a special no-op marker class or interface in each package that
        * serves no purpose other than being referenced by this attribute.
        * @return base packages to scan
        * @since 1.3.0
        */
       @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
       Class<?>[] scanBasePackageClasses() default {};
     
    }
复制代码

通过如上方式可以指定到元注解的属性【比如SpringBootApplication的scanBasePackageClasses   ===》ComponentScan的basePackageClasses】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值