• @ComponentScan比较


    ComponetScan 定义扫描规则

    1. value:指定要扫描的包
    2. excludeFilters=Filter[] 指定扫描的时候按照什么规则排除哪些组件。
    3. includeFilters=Filter[] 指定扫描的时候只需要包含哪些组件。(注意的是包扫描默认的是扫描所有的,也就是use-default-filters=”true”,所以需要设置为false。 这个和配置文件一样)
    • FilterType.ANNOTATION :按照注解的方式
    • FilterType.ASSIGNABLE_TYPE:按照给定的类型
    • FilterType.CUSTOM:使用自定义规则。 使用这个需要是TypeFilter的实现类
    • FilterType.CUSTOM使用 案例如下:
    • FilterType.ASPECTJ:使用ASPECTJ表达式(基本用不到) 
    • FilterType.REGEX :使用正则表达式

    例子

    @Configuration
    @ComponentScan(value = "feilong.example", useDefaultFilters = true, excludeFilters = {
            //过滤掉具体的注解下所有类
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
    //        //过滤掉具体的类
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ConfigTest2.class})
    },
            //includeFilter里面的Filter是并集
            includeFilters = {
                    @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
            }
    )
    public class MainConfig {
    
        @Bean
        public Person person() {
            return new Person("feilong", 20);
        }
    }

    类MyTypeFilter  是自定义Filter, 注意: 之前被过滤掉的类如果再自定义Filter中符合要求, 也会被重新放到IOC容器中.

    public class MyTypeFilter implements TypeFilter {
        @Override
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
    
            //获取注解metaData
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            Resource resource = metadataReader.getResource();
    
            //获取当前类信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            String strClassName = classMetadata.getClassName();
    
            System.out.println("通过自定义规则 ==>>>> " + strClassName);
            
            //返回true的类会被注册进IOC
            return strClassName.contains("Controller");
    
        }
    }

    @Import[快速的给容器中导入一个组件] 

    @Import的三种用法:

    (1)、 @Import(要导入容器中的组件);容器中就会自动的注册这个组件,id默认是全类名
    (2)、 ImportSelector :返回需要的组件的全类名的数组;
    (3)、 ImportBeanDefinitionRegistrar : 手动注册bean到容器中

     1. 组件注册-@Import-给容器中快速导入一个组件

    定义两个POJO类

    public class Color {
    }
    
    public class Red {
    }

    将此类对应的Bean导入IOC容器

    @Configuration
    @ComponentScan(value = "feilong.example")
    @Import({Color.class, Red.class})
    public class MainConfig {
    }

    2. 使用ImportSelector

    创建自定义MyImportSelector , 在方法selectImports 中返回要注入的类

    public class MyImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"feilong.example.springbootlearn.Color","feilong.example.springbootlearn.Red"};
        }
    }

    将自定义ImportSeletor加入配置文件

    @Configuration
    @ComponentScan(value = "feilong.example")
    @Import(MyImportSelector.class)
    public class MainConfig {
    }

    3. 使用 ImportBeanDefinitionRegistrar接口, 

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            registry.registerBeanDefinition("green", new RootBeanDefinition(Green.class));
        }
    }

    将自定义ImportSeletor加入配置文件

    @Configuration
    @ComponentScan(value = "feilong.example")
    @Import({MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
    public class MainConfig {
    }

    执行结果如下

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.annotation.internalCommonAnnotationProcessor
    org.springframework.context.event.internalEventListenerProcessor
    org.springframework.context.event.internalEventListenerFactory
    mainConfig
    feilong.example.springbootlearn.Color
    feilong.example.springbootlearn.Red
    person
    person3
    green

     使用FactoryBean注解

    创建自定义的一个FactoryBean

    public class MyColorFactoryBean implements FactoryBean<Color> {
        @Override
        public Color getObject() throws Exception {
            System.out.println("Creating Color Object by MyColorFactoryBean...");
            return new Color();
        }
    
    //控制是否为单例 
    // true:表示的就是一个单实例,在容器中保存一份 
    // false:多实例,每次获取都会创建一个新的bean
        @Override
        public boolean isSingleton() {
            return true;
        }
    
        @Override
        public Class<?> getObjectType() {
            return Color.class;
        }
    }

    配置为Bean

    @Configuration
    @ComponentScan(value = "feilong.example")
    public class MainConfig {
    
        @Bean
        public Person person() {
            return new Person("feilong", 20);
        }
    
        @Bean("person3")
        public Person personCondition() {
            return new Person("feilong", 30);
        }
    
        @Bean
        public MyColorFactoryBean colorFactoryBean(){
            return new MyColorFactoryBean();
        }
    }

    测试

    public class MainTest {
        public static void main(String[] args) throws InterruptedException {
    
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
    
            String[] strName = ((AnnotationConfigApplicationContext) applicationContext).getBeanDefinitionNames();
    
            for (String s : strName) {
                System.out.println(s);
            }
    
        //此处获取的是getObject对象, 即Color对象
            Color c = (Color) applicationContext.getBean("colorFactoryBean");
         //此处获取的是BeanFactory工厂对象本身
            MyColorFactoryBean myColorFactoryBean =(MyColorFactoryBean) applicationContext.getBean("&colorFactoryBean");
            System.out.println(c);
            System.out.println(myColorFactoryBean);
        }
    }
    
    /*
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.annotation.internalCommonAnnotationProcessor
    org.springframework.context.event.internalEventListenerProcessor
    org.springframework.context.event.internalEventListenerFactory
    mainConfig
    person
    person3
    colorFactoryBean
    Creating Color Object by MyColorFactoryBean...
    feilong.example.springbootlearn.Color@2a32de6c
    feilong.example.springbootlearn.MyColorFactoryBean@7692d9cc
    */

    注意, 使用FactoryBean(工厂Bean) 默认获取到的是工厂Bean调用方法getObject()获取到的对象, 如果要想获取到原来的Bean工厂本身,需要加上&, 


     Bean生命周期

    * 容器管理bean的生命周期:
      * 我们可以自定义初始化方法和销毁的方法:容器在bean进行到当前的生命周期的时候,来调用我们自定义的初始化方法和销毁方法
    * 构造(对象创建):
      * 单实例:在容器启动的时候创建对象
      * 多实例:在每次获取的时候来创建对象
    * 初始化方法:
      * 对象创建完成,并赋值好,调用初始化方法
    * 销毁方法:
      * 单实例的bean:在容器关闭的时候进行销毁
      * 多实例的bean:容器不会管理这个bean,容器不会调用销毁的方法


    生命周期-InitializingBeanDisposableBean

    定义测试类: 

    public class CarLifeCycle implements InitializingBean {
        public CarLifeCycle() {
            System.out.println("CarLifeCycle constructor...");
        }
    
        public void init() {
            System.out.println("CarLifeCycle...init...");
        }
    
        public void destroy() {
            System.out.println("CarLifeCycle...destroy...");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("接口 InitializingBean # afterPropertiesSet ");
        }
    }

    定义MyBeanPostProcessor

    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName + " => MyBeanPostProcessor .. before");
            return bean;
        }
        
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName + " => MyBeanPostProcessor .. after");
            return bean;
        }
    }

    注入IOC

    @Configuration
    @ComponentScan(value = "feilong.example")
    public class MainConfig {
    
        @Bean(initMethod = "init")
        public CarLifeCycle carLifeCycle(){
            return new CarLifeCycle();
        }
    }

    执行程序

    CarLifeCycle constructor...
    carLifeCycle => MyBeanPostProcessor .. before
    接口 InitializingBean # afterPropertiesSet 
    CarLifeCycle...init...
    carLifeCycle => MyBeanPostProcessor .. after
  • 相关阅读:
    多线程(一)高并发和多线程的关系
    spring源码浅析——IOC
    网络爬虫(java)
    数据结构—平衡二叉树
    设计模式—抽象工厂模式
    设计模式—工厂方法模式
    scala(二) Future执行逻辑解读
    java异常处理机制
    为什么覆写equals必须要覆写hashCode?
    Scala对MongoDB的增删改查操作
  • 原文地址:https://www.cnblogs.com/snow-man/p/10844696.html
Copyright © 2020-2023  润新知