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管理,这个框架的大部分内容都在做这块,需要继续加深理解。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森林老虎

混口饭吃嘿嘿

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值