戴着假发的程序员出品 抖音ID:戴着假发的程序员加粗样式 欢迎关注
ImportBeanDefinitionRegistrar接口
spring应用手册(第五部分)
ImportBeanDefinitionRegistrar接口提供了一个动态注入bean的方法,所以我们可以通过实现这个接口,然后自己手动注入bean。spring内部的bean的注入大部分都是使用这个套路。
当然这个接口的使用要配合注解@Import使用。下面我们先解释以下@Import注解。
@import注解可以用快速导入方式将一个Bean注册在spring的IOC容器中。
看看@Import的源码:
package org.springframework.context.annotation;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
属性value是class数组类型,所以我们可以传入Class。
注意@Import要注解在配置类上方。
一共有三种方式:
方式1:直接写对应要导入的class
/**
* @author 戴着假发的程序员
* @company http://www.boxuewa.com
* @description
*/
@Configuration
@Import(Coder.class)//Coder就会被注册在spring的IOC容器中
public class Appconfig {
}
方式二:注入实现了ImportSelector接口的类,默认会将这个接口中selectImports返回类数组注册在spring的容器中,spring的事务就是这样处理的,我们来看看源码:
@EnableTransactionManagement注解的源码:
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default 2147483647;
}
我们会发现spring使用@Import导入了TransactionManagementConfigurationSelector类,而TransactionManagementConfigurationSelector类就实现类ImportSelector接口,其中selectImports方法就返回类我们事务需要的一些类。关于这部分的详细讲解请查看ImportSelector接口的解释。
方式三:就是我们这一讲的主要内容,我们可以传入一个实现了ImportBeanDefinitionRegistrar接口的类,spring会按照ImportBeanDefinitionRegistrar接口中的registerBeanDefinitions方法逻辑进行bean的注册。
接下来我们来看一个案例:
我们准备一个Bean:
/**
* @author 戴着假发的程序员
* @company http://www.boxuewa.com
* @description
*/
@Component//使用spring的标准注解进行注解
public class Coder {
//构造方法
public Coder(){
System.out.println("实例化Coder对象");
}
}
我们自己实现一个ImportBeanDefinitionRegistrar:相信解释请看代码注释
package com.sp.registers;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
/**
* @author 戴着假发的程序员
* @company http://www.boxuewa.com
* @description 我们自己实现的ImportBeanDefinitionRegistrar
*/
public class DkRegister implements ImportBeanDefinitionRegistrar {
/**
* @param annotationMetadata 当前类的注解信息
* @param beanDefinitionRegistry 实现BeanDefinitionRegistry接口的对象,用于创建scanner对象,scanner对象可以扫描我们的类
**/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//创建ClassPathBeanDefinitionScanner对象,用于扫描我们的类,有两个参数
//参数1:实现BeanDefinitionRegistry接口的对象
//参数2:是否使用默认的类扫描过滤器,所谓默认类扫描过滤器就是指扫描spring的标准注解(@Component,@Controller,@Service,@Repository)我们这里就让spring扫描默认的注解
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry,true);
//扫描对应的包,找到有标准注解的类,加载并且注册到spring中。
scanner.scan("com.sp.beans");
}
}
配置类:
/**
* @author 戴着假发的程序员
* @company http://www.boxuewa.com
* @description
*/
@Configuration
@Import(DkRegister.class)//使用Import引入我们自己定义的类
public class Appconfig {
}
测试:
@Test
public void tesSpringImport(){
ApplicationContext ac =
new AnnotationConfigApplicationContext(Appconfig.class);
}
结果:
至此我们自己定义的ImportBeanDefinitionRegistrar已经完成了bean的快速注册。