BeanFactory 后处理器的作用
作用与bdMap创建完成后,通过对bdMap的操作(新增)来实现更多的功能拓展
-
ConfigurationClassPostProcessor 可以解析
-
@ComponentScan
-
@Bean
-
@Import
-
@ImportResource
-
-
MapperScannerConfigurer 可以解析
-
Mapper 接口
-
-
@ComponentScan, @Bean, @Mapper 等注解的解析属于核心容器(即 BeanFactory)的扩展功能
-
这些扩展功能由不同的 BeanFactory 后处理器来完成,其实主要就是补充了一些 bean 定义
package com.butch.a05;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
public class A05 {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config",Config.class);
//注册beanfactory后置处理器ConfigurationClassPostProcessor 解析// @ComponentScan @Bean @Import @ImportResource
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
//注册MapperScannerConfigurer,解析@mapperScaner
applicationContext.registerBean(MapperScannerConfigurer.class,beanDefinition -> {
beanDefinition.getPropertyValues().add("basePackage","com.butch.a05.mapper");
});
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
applicationContext.close();
}
}
package com.butch.a05;
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@ComponentScan("com.butch.a05.component")
public class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean(initMethod = "init")
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/db1");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
/*@Bean
public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory) {
MapperFactoryBean<Mapper1> factory = new MapperFactoryBean<>(Mapper1.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}
@Bean
public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory) {
MapperFactoryBean<Mapper2> factory = new MapperFactoryBean<>(Mapper2.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}*/
}
package com.butch.a05;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
public Bean1() {
log.debug("Bean1 我被 Spring 管理啦");
}
}
package com.butch.a05.component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class Bean2 {
private static final Logger log = LoggerFactory.getLogger(Bean2.class);
public Bean2() {
log.debug("Bean2 我被 Spring 管理啦");
}
}
模拟解析 @ComponentScan
-
Spring 操作元数据的工具类 CachingMetadataReaderFactory
-
通过注解元数据(AnnotationMetadata)获取直接或间接标注的注解信息
-
通过类元数据(ClassMetadata)获取类名,AnnotationBeanNameGenerator 生成 bean 名
-
解析元数据是基于 ASM 技术
版本1.0未解耦
package com.butch.a05;
import com.fasterxml.jackson.dataformat.xml.util.AnnotationUtil;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
import java.io.IOException;
public class A05 {
public static void main(String[] args) throws IOException {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config",Config.class);
// //注册beanfactory后置处理器ConfigurationClassPostProcessor 解析// @ComponentScan @Bean @Import @ImportResource
// applicationContext.registerBean(ConfigurationClassPostProcessor.class);
// //注册MapperScannerConfigurer,解析@mapperScaner
// applicationContext.registerBean(MapperScannerConfigurer.class,beanDefinition -> {
// beanDefinition.getPropertyValues().add("basePackage","com.butch.a05.mapper");
// });
//模拟componscan注解
ComponentScan annotation = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (annotation != null){
//获取包名
for (String s : annotation.basePackages()) {
System.out.println("s = " + s);
//转化路径为包名
// com.butch.a05.component -> classpath*:com/butch/a05/component/**/*.class
String path = "classpath*:" + s.replace(".", "/") + "/**/*.class";
System.out.println("path = " + path);
//通过context扩展获取资源, 获取扫描到包class文件集合
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
Resource[] resources = applicationContext.getResources(path);
for (Resource resource : resources) {
// System.out.println("resource = " + resource);
//获取类的元信息
MetadataReader metadataReader = factory.getMetadataReader(resource);
System.out.println("metadataReader.getClassMetadata().getClassName() = " + metadataReader.getClassMetadata().getClassName());
System.out.println("metadataReader.getAnnotationMetadata().hasAnnotatedMethods(Component.class.getName()) = " + metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
//派生注解
System.out.println("metadataReader.getAnnotationMetadata().hasAnnotatedMethods(Component.class.getName()) = " + metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));
//当加了component注解或者其派生注解的时候 注册bd到map中
if (metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName()) || metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName())){
//构造一个bd
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();
//获取bean的名字
String beanName = generator.generateBeanName(bd, applicationContext);
//注册bd
applicationContext.registerBeanDefinition(beanName,bd);
}
}
}
}
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
applicationContext.close();
}
}
版本2.0解耦
package com.butch.a05;
import com.fasterxml.jackson.dataformat.xml.util.AnnotationUtil;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
import java.io.IOException;
public class A05 {
public static void main(String[] args) throws IOException {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config",Config.class);
// //注册beanfactory后置处理器ConfigurationClassPostProcessor 解析// @ComponentScan @Bean @Import @ImportResource
// applicationContext.registerBean(ConfigurationClassPostProcessor.class);
// //注册MapperScannerConfigurer,解析@mapperScaner
// applicationContext.registerBean(MapperScannerConfigurer.class,beanDefinition -> {
// beanDefinition.getPropertyValues().add("basePackage","com.butch.a05.mapper");
// });
applicationContext.registerBean(ComponentScanPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
applicationContext.close();
}
}
package com.butch.a05;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
public class ComponentScanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry applicationContext) throws BeansException {
//模拟componscan注解
try {
ComponentScan annotation = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (annotation != null) {
//获取包名
for (String s : annotation.basePackages()) {
System.out.println("s = " + s);
//转化路径为包名
// com.butch.a05.component -> classpath*:com/butch/a05/component/**/*.class
String path = "classpath*:" + s.replace(".", "/") + "/**/*.class";
System.out.println("path = " + path);
//通过context扩展获取资源, 获取扫描到包class文件集合
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
// Resource[] resources = applicationContext.getResources(path);
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
for (Resource resource : resources) {
// System.out.println("resource = " + resource);
//获取类的元信息
MetadataReader metadataReader = factory.getMetadataReader(resource);
System.out.println("metadataReader.getClassMetadata().getClassName() = " + metadataReader.getClassMetadata().getClassName());
System.out.println("metadataReader.getAnnotationMetadata().hasAnnotatedMethods(Component.class.getName()) = " + metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
//派生注解
System.out.println("metadataReader.getAnnotationMetadata().hasAnnotatedMethods(Component.class.getName()) = " + metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));
//当加了component注解或者其派生注解的时候 注册bd到map中
if (metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName()) || metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName())) {
//构造一个bd
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();
//获取bean的名字
String beanName = generator.generateBeanName(bd, applicationContext);
//注册bd
applicationContext.registerBeanDefinition(beanName, bd);
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
@Override// context.refresh
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
总结
-
获取componentScan注解的basepage属性值,即为包名,并将其转为路径
-
获取类路径下的所有资源类文件,获取其元数据
-
根据其元数据判断类中是否有component注解及其派生注解
-
有的话注册bd到map中
模拟解析 @Bean
版本1.0未解耦
package com.butch.a05;
import com.fasterxml.jackson.dataformat.xml.util.AnnotationUtil;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Set;
public class A05 {
public static void main(String[] args) throws IOException {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config",Config.class);
// //注册beanfactory后置处理器ConfigurationClassPostProcessor 解析// @ComponentScan @Bean @Import @ImportResource
// applicationContext.registerBean(ConfigurationClassPostProcessor.class);
// //注册MapperScannerConfigurer,解析@mapperScaner
// applicationContext.registerBean(MapperScannerConfigurer.class,beanDefinition -> {
// beanDefinition.getPropertyValues().add("basePackage","com.butch.a05.mapper");
// });
// applicationContext.registerBean(ComponentScanPostProcessor.class);
//获取类元信息
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
MetadataReader metadataReader = factory.getMetadataReader(new ClassPathResource("com/butch/a05/Config.class"));
//所有包含@bean注解的方法
Set<MethodMetadata> annotatedMethods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : annotatedMethods) {
System.out.println("annotatedMethod = " + method.getMethodName());
//获取工厂bd
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
beanDefinitionBuilder.setFactoryMethodOnBean(method.getMethodName(),"config");
beanDefinitionBuilder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
//处理属性提取注入的初始化
if (initMethod.length() > 0){
beanDefinitionBuilder.setInitMethodName(initMethod);
}
//注册bd
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
applicationContext.registerBeanDefinition(method.getMethodName(),beanDefinition);
}
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
applicationContext.close();
}
}
版本2.0解耦
package com.butch.a05;
import com.fasterxml.jackson.dataformat.xml.util.AnnotationUtil;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Set;
public class A05 {
public static void main(String[] args) throws IOException {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config",Config.class);
// //注册beanfactory后置处理器ConfigurationClassPostProcessor 解析// @ComponentScan @Bean @Import @ImportResource
// applicationContext.registerBean(ConfigurationClassPostProcessor.class);
// //注册MapperScannerConfigurer,解析@mapperScaner
// applicationContext.registerBean(MapperScannerConfigurer.class,beanDefinition -> {
// beanDefinition.getPropertyValues().add("basePackage","com.butch.a05.mapper");
// });
// applicationContext.registerBean(ComponentScanPostProcessor.class);
// //获取类元信息
// CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
// MetadataReader metadataReader = factory.getMetadataReader(new ClassPathResource("com/butch/a05/Config.class"));
// //所有包含@bean注解的方法
// Set<MethodMetadata> annotatedMethods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
// for (MethodMetadata method : annotatedMethods) {
// System.out.println("annotatedMethod = " + method.getMethodName());
// //获取工厂bd
// BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
// String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
// beanDefinitionBuilder.setFactoryMethodOnBean(method.getMethodName(),"config");
// beanDefinitionBuilder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
// //处理属性提取注入的初始化
// if (initMethod.length() > 0){
// beanDefinitionBuilder.setInitMethodName(initMethod);
// }
// //注册bd
// AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
// applicationContext.registerBeanDefinition(method.getMethodName(),beanDefinition);
// }
applicationContext.registerBean(AtBeanPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
applicationContext.close();
}
}
package com.butch.a05;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import java.io.IOException;
import java.util.Set;
public class AtBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
try {
//获取类元信息
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
MetadataReader metadataReader = factory.getMetadataReader(new ClassPathResource("com/butch/a05/Config.class"));
//所有包含@bean注解的方法
Set<MethodMetadata> annotatedMethods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : annotatedMethods) {
System.out.println("annotatedMethod = " + method.getMethodName());
//获取工厂bd
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
beanDefinitionBuilder.setFactoryMethodOnBean(method.getMethodName(),"config");
beanDefinitionBuilder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
//处理属性提取注入的初始化
if (initMethod.length() > 0){
beanDefinitionBuilder.setInitMethodName(initMethod);
}
//注册bd
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition(method.getMethodName(),beanDefinition);
}
}catch (IOException e){
e.printStackTrace();
}
}
@Override//refresh
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
总结
-
获取该类的元数据
-
获取类中所有标注@bean注解的方法
-
根据方法构造bd,注册到Map中
模拟解析@mapperscan
添加单个mapper可以使用@bean
@Bean
public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory) {
MapperFactoryBean<Mapper1> factory = new MapperFactoryBean<>(Mapper1.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}
@Bean
public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory) {
MapperFactoryBean<Mapper2> factory = new MapperFactoryBean<>(Mapper2.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}
扫描添加mapper
package com.butch.a05;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import java.io.IOException;
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
try {
//获取mapper对应的资源
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:com/butch/a05/mapper/**/*.class");
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator annotationBeanNameGenerator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
//获取资源元数据
MetadataReader reader = factory.getMetadataReader(resource);
ClassMetadata classMetadata = reader.getClassMetadata();
//如果该类是一个接口则注册bd
if (classMetadata.isInterface()){
AbstractBeanDefinition bd1 = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
//mapper的泛型类型
.addConstructorArgValue(classMetadata.getClassName())
//set构造bytype
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
//由于bean名字生成都是MapperFactoryBean,因此根据泛型类型再生成一个bd获取名字
AbstractBeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
//获取名字
String beanName = annotationBeanNameGenerator.generateBeanName(bd2, beanDefinitionRegistry);
//注册
beanDefinitionRegistry.registerBeanDefinition(beanName,bd1);
}
}
}catch (IOException e){
e.printStackTrace();
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
总结
-
单个mapper可以使用@bean注入
-
多个mapper使用mapperscan
-
获取mapperscan的包转为类路径,并获取资源
-
获取资源的下类的元信息
-
根据类元信息判断类是否为接口,是否有mapper注解
-
有则注册mpper,由于获取名字的时候使用的mapperfactorybean,获取到的名字都一样,因新建一个bd,根据类的元信息获取beanname
-