• Spring-注解


    Spring 注解分类

    在这里插入图片描述
    在这里插入图片描述

    Spring 注解驱动模型

    Spring 元注解
    @Documented
    @Retention()
    @Target()
    // 可以继承相关的属性
    @Inherited
    @Repeatable()
    
    Spirng 模式注解

    @ComponentScan 原理
    ClassPathScanningCandidateComponentProvider#findCandidateComponents

    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
    	if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
    		return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
    	}
    	else {
    		return scanCandidateComponents(basePackage);
    	}
    }
    
    组合注解

    比如@RestController,@SpringBootApplication
    注解转换为AnnotationAttributes然后进行合并统一

    Spring属性别名

    显性别名:
    在这里插入图片描述
    隐式别名:
    这个组合注解
    继承EnableAutoConfiguration的属性,用隐式别名来表达,也就是直接拿过来不需要改变它的值:
    在这里插入图片描述
    如果说我们要补充语义,引用某个属性,自己定义新的属性名称来引用父类的:
    在这里插入图片描述
    举例如果我们要派生这个注解,我们不可能在注解里面写死扫描路径,这个时候就要通过隐式别名来继承注解ComponentScan的属性,这样我们就可以配置scanBasePackages

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @ComponentScan
    public @interface MyComponentScan {
        @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
        String scanBasePackages() default "";
    
    }
    

    我们也可以这样:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @ComponentScan
    public @interface MyComponentScan {
    	// 传递性别名 basePackages -> value value -> scanBasePackages
        @AliasFor(annotation = ComponentScan.class, attribute = "value")
        String scanBasePackages() default "";
    }
    

    Spring属性覆盖

    注解和原注解出现同名属性的时候会覆盖原注解的属性

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @ComponentScan
    public @interface MyComponentScan {
        @AliasFor(annotation = ComponentScan.class, attribute = "value")
        String scanBasePackages() default "";
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @MyComponentScan
    public @interface MyComponentScan2 {
        // 显示覆盖
        String[] scanBasePackages() default "";
    	// 隐式覆盖 
        @AliasFor(attribute = "scanBasePackages")
        String[] packages() default {};
    }
    @MyComponentScan2(packages = {"com.yong.annotationpkg"})
    // packages 覆盖scanBasePackages scanBasePackages覆盖MyComponentScan scanBasePackages scanBasePackages 引用的是ComponentScan
    

    Spring @Enable 模块驱动

    在这里插入图片描述
    案例1通过@Configration实现

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(DemoConfig.class)
    public @interface EnableDemo {
    
    }
    @Configuration
    public class DemoConfig {
        @Bean
        Person person() {
            Person person = new Person();
            person.setName("liy");
            person.setId(11L);
            return person;
        }
    }
    
    @EnableDemo
    public class EnableAnnotationDemo {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.register(EnableAnnotationDemo.class);
            context.refresh();
            Person bean = context.getBean(Person.class);
            System.out.println(bean);
        }
    }
    

    案例2通过ImportSelector接口实现:

    public class DemoImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"com.yong.annotationpkg.DemoConfig"};
        }
    }
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(DemoImportSelector.class)
    public @interface EnableDemo {
    
    }
    @EnableDemo
    public class EnableAnnotationDemo {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.register(EnableAnnotationDemo.class);
            context.refresh();
            Person bean = context.getBean(Person.class);
            System.out.println(bean);
        }
    }
    

    案例3通过

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(DemoImportBeanDefinitionRegister.class)
    public @interface EnableDemo {
    
    }
    public class DemoImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
            AnnotatedBeanDefinition annotatedBeanDefinition = new AnnotatedGenericBeanDefinition(DemoConfig.class);
            registry.registerBeanDefinition("demoConfig", annotatedBeanDefinition);
        }
    }
    
    Spring 条件注解

    在这里插入图片描述

    @Configuration
    public class ProfileDemo {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.register(ProfileDemo.class);
            ConfigurableEnvironment environment = context.getEnvironment();
            // 兜底方案
            environment.setDefaultProfiles("odd");
            // 激活方案
            environment.setActiveProfiles("even");
            context.refresh();
            Object odd = context.getBean(Integer.class);
            System.out.println(odd);
            context.close();
        }
        // 激活不同的环境注册不同的Bean
        @Bean
        @Profile("odd")
        public Integer odd() {
            return 2;
        }
        @Bean
        @Profile("even")
        public Integer even() {
            return 1;
        }
    }
    

    自定义实现:

    public class EvenProfileCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            Environment environment = context.getEnvironment();
            return environment.acceptsProfiles("even");
        }
    }
    @Bean
     @Conditional(EvenProfileCondition.class)
     public Integer even() {
         return 1;
     }
    

    ConditionEvaluator#shouldSkip
    在这里插入图片描述

    参考资料
    小马哥核心编程思想

  • 相关阅读:
    Java排序算法之基数排序
    java之string类用法详解
    CountDownLatch使用错误+未最终断开连接导致线程池资源耗尽
    使用小程序实现AI动漫脸特效
    Springboot毕设项目基于JavaWeb的健身房管理系统102j4(java+VUE+Mybatis+Maven+Mysql)
    Linux之SELinux
    NIO- Handler业务处理器
    Linux 进程管理之命名空间
    电商新趋势:阿里巴巴1688.item_password API引领智能分享新风尚
    亚马逊频繁封号,跨境电商卖家如何应对?
  • 原文地址:https://blog.csdn.net/qq_43259860/article/details/139278767