spring扫描自定义注解对应的类并装入IOC容器

比特逐影鹤
• 阅读 7186

前言

本文继笔者学习mybatis源码后,仿照mybatis利用spring的拓展点将Mapper接口的代理类装入IOC的方法,实现自定义注解,让spring将指定包中有此注解的类装配进IOC容器来管理之,最终是放入容器的单例池中。

实现

1. 自定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface XxgComponent {
}

2. XxgComponentScannerConfigurer

2.1 实现BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor,是spring给我们的一个拓展点,其自身继承自BeanFactoryPostProcessor接口。
实现此接口的类,spring在初始化之后,会调用其以下两个方法:

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;

故我们可以在其实现类对应的方法中,执行我们的业务逻辑--即让spring扫描我们自定义注解对应的类。

2.2 代码

public class XxgComponentScannerConfigurer implements BeanDefinitionRegistryPostProcessor {
     private String basePackages;
     public void setBasePackages(String basePackages) {
            this.basePackages = basePackages;
     }
     @Override
     public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
            // left intentionally blank
     }
     @Override
     public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            XxgComponentScanner scanner = new XxgComponentScanner(registry);
         scanner.registerFilters();
         scanner.scan(basePackages);
     }
}

3.扫描类XxgComponentScanner

3.1 ClassPathBeanDefinitionScanner

此类是spring用于扫描bean的类,

  1. doScan()方法会根据配置的拦截器规则,来将需要的类装配成BeanDefinitionHolder对象并返回。
  2. 调用其scan()方法,其自身先调用doScan()方法,然后会将扫描到的BeanDefinitionHolder对象放入IOC容器

故,我们可以继承其类,然后:

  1. 不使用其默认拦截规则,而是根据我们自定义注解来拦截
  2. 重写其doScan()方法,首先调用父类的doScan()获取到有我们自定义注解的BeanDefinitionHolder对象们,然后可以遍历操作之,更改一些我们需要的参数,比如设置scope为单例等。

3.2 代码

public class XxgComponentScanner extends ClassPathBeanDefinitionScanner {
    public XxgComponentScanner(BeanDefinitionRegistry registry) {
        // 第二个参数:useDefaultFilters
        // 设置为false,不使用默认拦截器
        super(registry, false);
    }
    @Override
     public Set<BeanDefinitionHolder> doScan(String... basePackages) {
            // 利用spring的扫描方法,扫描mapper接口所在的包,获取所有BeanDefinitionHolder
         Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
         processBeanDefinitions(beanDefinitions);
         return beanDefinitions;
     }
     private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitionHolders) {
        for (BeanDefinitionHolder holder : beanDefinitionHolders) {
            GenericBeanDefinition beanDefinition = (GenericBeanDefinition)holder.getBeanDefinition();
 beanDefinition.setScope("singleton");
        System.out.println(beanDefinition.getBeanClassName());
        }
    }
    // 定义拦截器,让spring装配我们需要的对象到IOC容器
    public void registerFilters() {
        // 设置 只扫描有@XxgComponent注解的类
     addIncludeFilter(new AnnotationTypeFilter(XxgComponent.class));
     // 设置 忽略 package-info.java addExcludeFilter((metadataReader, metadataReaderFactory) -> {
                String className = metadataReader.getClassMetadata().getClassName();
        return className.endsWith("package-info");
     });
   }
}

4.让spring管理我们的XxgComponentScannerConfigurer

<!-- 测试自定义装配bean注解-->
 <bean class="com.dbc.springMybatis.util.XxgComponentScannerConfigurer">
   <property name="basePackages" value="com.dbc.springMybatis.myBean"/>
 </bean>
点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
spring源码
SpringIOC容器源码解析系列,建议大家按顺序阅读,欢迎讨论(_spring源码均为4.1.6.RELEASE版本_)1.Spring源码IOC容器(一)构建简单IOC容器(https://my.oschina.net/u/2377110/blog/902073)2.Spring源码IOC容器(二)Bean的定位解析注
Wesley13 Wesley13
3年前
SSM的基本知识点
\SpringSpring框架是一个容器,它的主要作用是创建和管理对象。Spring框架实现了解耦。Spring框架通过DI实现了IoC。关于Spring框架,必须掌握和理解的:1. Spring的基本概念与特性;2. 常用的注解:通用的4个注解,自动装配的注解;3.
Easter79 Easter79
3年前
spring注解
随着越来越多地使用Springboot敏捷开发,更多地使用注解配置Spring,而不是Spring的applicationContext.xml文件。Configuration注解:Spring解析为配置类,相当于spring配置文件Bean注解:容器注册Bean组件,默认id为方法名@Configurat
Easter79 Easter79
3年前
SpringIOC官方文档解读
IoC容器本章介绍了Spring的控制反转(IoC)容器。1.1。SpringIoC容器和Bean简介本章介绍了反转控制(IoC)原则的Spring框架实现。IoC也称为依赖注入(DI)。在此过程中,对象可以通过①构造函数参数(),②工厂方法的参数③或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依
Stella981 Stella981
3年前
Spring 的 IOC 容器
一.BeanFactory 1\.在spring中,最基本的IOC容器接口是BeanFactory这个接口为具体的IOC容器的实现做了最基本的功能规定。  2\.在BeanFactory只对IOC容器的基本行为做了定义,根本不关心你的bean是怎样定义怎样加载的;XmlBeanFactory就是针对最
Easter79 Easter79
3年前
Spring高级进阶:BeanFactoryPostProcessor
BeanFactoryPostProcessor是实现spring容器功能扩展的重要接口,例如修改bean属性值,实现bean动态代理等。很多框架都是通过此接口实现对spring容器的扩展,例如mybatis与spring集成时,只定义了mapper接口,无实现类,但spring却可以完成自动注入,是不是很神奇?本文将通过简单的例子,展现BeanFacto
Easter79 Easter79
3年前
Spring学习笔记一
IOC容器里配置beanapplicationContext.xml必须有个无参的构造器class:bean的全类名通过beanid获得这个bean必须唯一spring提供2种IOC容器容器实现方式beanfactory用在spring本身applicationContext用在开发者配置方式相同
Easter79 Easter79
3年前
Spring与Mybatis环境搭建
SH框架的结合几乎家喻户晓,但是一般的中小项目,使用Spring和MyBatis就够了,而且MyBatis轻便好使,易上手,值得大家尝试一次。  开篇简介:  Spring:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。两个重要模块:Spring面向方面编程(AOP)和控制反转(IOC)容器。控制反转模
Easter79 Easter79
3年前
Spring系列(五) 容器初始化过程源码
IoC/DI的概念容器是Spring的核心之一(另一个核心是AOP).有了容器,IOC才可能实现.什么使IoC?IoC就是将类自身管理的与其由依赖关系的对象的创建/关联和管理交予容器实现,容器按照配置(比如xml文件)来组织应用对象的创建和关联.什么使DI?DI是IoC的实现方式,由容器
Wesley13 Wesley13
3年前
Spring常用注解
使用注解来构造IoC容器用注解来向Spring容器注册Bean。需要在applicationContext.xml中注册<context:componentscanbasepackage”pagkage1\,pagkage2,…,pagkageN\”/。如:在basepackage指明一个包
Easter79 Easter79
3年前
Spring面试题总结
1、Spring是什么?Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于java的配置。主要由以下几个模块组成:SpringCore:核心类库,提供IOC服务;