zoukankan      html  css  js  c++  java
  • Spring注解开发之@Conditional和@Import

    @Scope设置组件作用域

    @Configuration
    public class MainConfig2 {
    
        @Bean("person2")
        // value: 默认prototype,singleyon request同一个请求创建一个实例,session同一个session创建一个实例
        // singleton时,ioc容器启动会调用方法创建对象到ioc中,以后就从容器中拿
        // prototype: 启动不会创建,获取的时候才会创建实例
        @Scope("prototype")
        public Person person(){
            return new Person("jack",32);
        }
    }
    
        @Test
        public void test02(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for (String beanDefinitionName : beanDefinitionNames) {
                System.out.println(beanDefinitionName);
            }
    
    //        Object person = applicationContext.getBean("person");  与注册的id不同会找不到报错
            Object person1 = applicationContext.getBean("person2");
            Object person2 = applicationContext.getBean("person2");
    
            System.out.println(person1==person2);  // scope prototype时会报错
    
        }
    }
    

    @Lazy懒加载:

    // 不加@Lazy
    @Configuration
    public class MainConfig2 {
    
        @Bean("person2")
        public Person person(){
            System.out.println("创建了jack实例");  // 会打印
            return new Person("jack",32);
        }
    }
    
    // 有lazy注解
    @Configuration
    public class MainConfig2 {
    
        @Bean("person2")
        @Lazy
        public Person person(){
            System.out.println("创建了jack实例");  // 不会打印,只有第一次获取此bean的时候会打印
            return new Person("jack",32);
        }
    }
    
    
    @Test
    public void test02(){
      AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
      String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
      for (String beanDefinitionName : beanDefinitionNames) {
        System.out.println(beanDefinitionName);
      }
    }
    
    

    @Conditional根据条件加载

    • 此注解如果标在类上,表示满足当前条件,这个类中配置的所有bean才会生效

    配置类

    @Configuration
    // @Conditional(ConditionTest.class) 
    public class MainConfig2 {
    
    @Conditional(ConditionTest.class) 
        @Bean("jazz")
        public Person person01(){
            return new Person("deron",24);
        }
    
        @Conditional(ConditionTest2.class)
        @Bean("hornet")
        public Person person02(){
            return new Person("paul",22);
        }
    }
    

    Condition

    public class ConditionTest implements Condition {
    
        /**
         *
         * @param conditionContext 判断条件能使用的上下文
         * @param annotatedTypeMetadata 注释信息
         * @return
         */
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            // 1.可以获取到ioc使用的beanFactory
            ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
            // 2.获取到类加载器
            ClassLoader classLoader = conditionContext.getClassLoader();
            // 3.获取bean定义的注册类(可以获取容器中bean的注册情况,也可以给容器中注册bean)
            BeanDefinitionRegistry registry = conditionContext.getRegistry();
            // 4.获取当前环境信息
            Environment environment = conditionContext.getEnvironment();
    
    
            String property = environment.getProperty("os.name");
            assert property != null;
            return property.contains("Mac");
        }
    }
    
    
    public class ConditionTest2 implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            Environment environment = conditionContext.getEnvironment();
            String property = environment.getProperty("os.name");
            assert property != null;
            return property.contains("windows");
        }
    }
    

    测试类

        @Test
        public void test03(){
            String[] beanNamesForType = applicationContext.getBeanNamesForType(Person.class);
            for (String s : beanNamesForType) {
                System.out.println(s);  // 根据你的操作系统实现注册
            }
        }
    

    @Import导入组件

    1. 根据Class导入

    可以快速将类导入到容器中

    自定义class
    
    public class Color {
    }
    

    在配置类中可以快速导入到容器

    @Configuration
    @Import(Color.class)
    public class MainConfig2 {
    
    }
    

    2. ImportSelector导入

    根据全类名导入

    @Import({Color.class, MyImportSelector.class})
    
    public class MyImportSelector implements ImportSelector {
    
        // 返回值就是导入到容器中的组件全雷鸣
    
        /**
         *
         * @param annotationMetadata 当前标注@Import注解的类的所有信息
         * @return
         */
        @Override
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            return new String[]{"com.hjj.bean.Red"};
        }
    
    }
    
    

    3. MyImportBeanDefinitionRegistrar导入

    @Import({Color.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
    
    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Blue.class);
            registry.registerBeanDefinition("blue",rootBeanDefinition);
        }
    }
    

    FactoryBean

    定义一个工厂即成FactoryBean

    public class ColorFactoryBean implements FactoryBean<Color> {
    
        // 返回一个Color对象,这个对象会添加到容器中
        @Override
        public Color getObject() throws Exception {
            System.out.println("getObject");
            return new Color();
        }
    
        @Override
        public Class<?> getObjectType() {
            return Person.class;
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    }
    
    

    配置

        @Bean
        public ColorFactoryBean colorFactoryBean(){
            return new ColorFactoryBean();
        }
    

    测试时打印结果

        @Test
        public void test4(){
            printBeans(applicationContext);
            System.out.println("======");
            // 工厂bean获取的是getObject创建的对象
            Object colorFactoryBean = applicationContext.getBean("colorFactoryBean");
            System.out.println(colorFactoryBean.getClass());
            --》 class com.hjj.bean.Color
    
            // 获取工厂bean
            Object bean = applicationContext.getBean("&colorFactoryBean");
            System.out.println(bean.getClass());
            --》 class com.hjj.bean.ColorFactoryBean
        }
    

    总结

    给容器中注册组件

    1. 包扫描 + 组件标注注解(@Controller等)
    2. @Bean 导入的第三方包里面的组件
    3. @Import
      • @Import
      • ImportSelector:返回需要导入的组件的全类名数组
      • ImportBeanDefinitionRegistrar:手动注册bean到容器
    4. 使用Spring提供的FactoryBean(工厂Bean)
  • 相关阅读:
    Object类的方法简记
    run()和start()调用问题简记
    面向对象设计
    关于JVM的简记
    操作运算符的简记
    jdbc简记
    synchronized的简记
    垃圾回收的一些简记
    java.io.IOException: Stream closed
    Java-文件名、目录名或卷标语法不正确
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/13661807.html
Copyright © 2011-2022 走看看