当前位置: 首页 > news >正文

@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

 

转载于:https://www.cnblogs.com/snow-man/p/10844696.html

相关文章:

  • GAN 原理及公式推导
  • Mybatis find_in_set 子查询,替代 in
  • 指令——free
  • 吴裕雄 python 神经网络——TensorFlow 循环神经网络处理MNIST手写数字数据集
  • 三层架构详细介绍
  • ElasticSearch Roaring bitmap 和跳表联合查询
  • Redis(一)----安装及基本使用
  • Spring Cloud(3):Ribbon的使用
  • RESTful API批量操作的实现
  • Node.js原生路由
  • C语言基础:break语句使用范例源码
  • 第六次实训作业
  • C# — MongoDB数据库安装
  • k8s 三节点签发所需证书
  • 经典书籍
  • [译] 怎样写一个基础的编译器
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Cumulo 的 ClojureScript 模块已经成型
  • ES2017异步函数现已正式可用
  • gitlab-ci配置详解(一)
  • idea + plantuml 画流程图
  • leetcode46 Permutation 排列组合
  • Map集合、散列表、红黑树介绍
  • Promise面试题,控制异步流程
  • v-if和v-for连用出现的问题
  • vue总结
  • 让你的分享飞起来——极光推出社会化分享组件
  • 数组大概知多少
  • 微服务核心架构梳理
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • #1015 : KMP算法
  • $.ajax中的eval及dataType
  • (09)Hive——CTE 公共表达式
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (4)(4.6) Triducer
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (Java)【深基9.例1】选举学生会
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • .NET Core 2.1路线图
  • .net FrameWork简介,数组,枚举
  • .NET 指南:抽象化实现的基类
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET成年了,然后呢?
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET使用存储过程实现对数据库的增删改查
  • .Net中ListT 泛型转成DataTable、DataSet
  • [20171113]修改表结构删除列相关问题4.txt
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [BUUCTF]-Reverse:reverse3解析