• spring注解驱动开发----组件注册自定义TypeFilter指定过滤规则思考


    在看这篇文章的时候,spring注解驱动开发,一直有2个疑惑

    • 1.为什么MyTypeFilter这个类,我们只是定义了这个类,并没有创建它的对象,它的方法是怎么被调用的嘞,我们知道,非static方法的调用,必须借助这个方法本身所在的类的对象完成,那我们猜测这个类是spring帮我们创建的,但是什么时候创建,怎么创建,还是要留个疑问。
    • 2.没有标注@Component等注解,但是也被注入了spring容器,是什么原因?

    带着以上的2个疑问,开始分析猜测,看代码:

    public class MyTypeFilter implements TypeFilter {
    
       public MyTypeFilter() {
            System.out.println("我诞生了");
        }
    
        @Override
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
            //获取到当前正在扫描的类的信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            String className = classMetadata.getClassName();
            System.out.println("通过自定义的匹配规则--->"+className);
            if (className.contains("er")) {
                return true;
            }
            return false;
        }
    }
    
    @Configuration //告诉Spring这是一个配置类
    //@ComponentScan(value = "org.cc")//相当于是xml配置文件里面的<context:component-scan base-package="org.cc"/>
    @ComponentScans(value = {
            @ComponentScan(value = "org.cc",includeFilters = {
                    //自定义匹配的规则,org.cc这个包下的所有类都按照这个规则去进行匹配,如果符合就注入容器,当然也包括MyTypeFilter类本身
                    @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
            },useDefaultFilters = false)
    })
    public class MainConfig {
    
        //相当于xml配置文件中的<bean>标签,告诉容器注册一个bean
        //之前xml文件中<bean>标签有bean的class类型,那么现在注解方式的类型当然也就是返回值的类型
        //之前xml文件中<bean>标签有bean的id,现在注解的方式默认用的是方法名来作为bean的id
        @Lazy
        @Bean
        public Person person() {
            System.out.println("给容器中添加person");
            return new Person("lisi",20);
        }
    
        /**
         *  现在下面的两个bean注册到IOC容器是要条件的:
         *  1.如果系统是windows,给容器注册("bill")
         *  1.如果系统是linux,给容器注册("linus")
         * @return
         */
        @Bean("bill")
        public Person person01() {
            return new Person("Bill Gates",62);
        }
    
        @Bean("linus")
        public Person person02() {
            return new Person("linus",48);
        }
    }
    

    在这里插入图片描述
    首先分析第1步,这个理解了,就能明白第一个问题,在spring容器未获取之前,这个类就被实例化过,要不它的方法也不能被调用是不,这里跟进源码去看
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    可以看到,我们定义这个类,会被spring的注解扫描器扫描到,帮助我们去创建这个对象,然后使用这个对象的功能,这个时候,还没有被放入容器中,我们可以修改下MyTypeFilter的方法,来验证下,
    在这里插入图片描述
    改了之后的运行结果:
    在这里插入图片描述
    可以看到容器中的所有对象里,不再包含MyTypeFilter这个类。至于为啥mianConfig、person、bill、linus这几个存在容器中,是因为它们不依赖那个filter,看下图:
    在这里插入图片描述
    MyTypeFilter这里结合ComponentScan注解使用的含义是,在org.cc这个包下的所有类,只要类名里带"er"字符,就会被扫描到放进容器里面。看到这里想必就理解上面的2个问题了吧。

    以前我一直有个疑惑,这个类什么时候应该我们自己去主动注入,什么时候我们不用注入就可以使用呐,以这个MyTypeFilter为例,我们继承spring提供的TypeFilter接口,在程序启动的时候,spring框架需要使用MyTypeFilter这个类,借助这个类的方法(虽然是我们写的)去判断哪些类应该注入spring容器,即这个类是spring框架要用的,自然由spring框架帮助我们实例化,然后调用对应的方法,但是像一些我们整合redis的配置类等代码,由于是spring项目启动后我们去使用这个类提供的功能,就需要我们告诉spring,你初始化容器的时候,给我整个这个类的对象,我后面会拿过来用。

    其实spring的ioc就是做控制反转,将对象交由spring管理,这个框架的大部分内容都在做这块,需要继续加深理解。

    艾欧尼亚,昂扬不灭,为了更美好的明天而战(#^.^#)
  • 相关阅读:
    pigeon
    servlet
    Linux (centos6.5) 安装Node和pm2
    git 常用命令
    git本地仓库推送代码到远程仓库
    linux 服务器 磁盘空间查看清理
    阿里云 Kubenetes容器 时区相差8小时 设置环境变量
    推荐一个简易易懂的ElasticSearch 入门学习站
    ElasticSearch 设置索引mapping 文档类型,重置elastic密码
    linux 查看系统各项指标(资源,内存)
  • 原文地址:https://www.cnblogs.com/lovelywcc/p/15501267.html
Copyright © 2020-2023  润新知