Spring底层原理(四)

Spring底层原理(四)

本章内容

模拟实现Spring中的几个常见BeanFactory后置处理器

常见的BeanFactory后置处理器
java 复制代码
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config",Config.class);
context.registerBean(ConfigurationClassPostProcessor.class);//解析@ComponentScan @Bean @Import @ImportResource
ontext.registerBean(MapperScannerConfigurer.class,bd->{
	bd.getPropertyValues().add("basePackage","com.vmware.mapper");
});
//初始化容器
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
    System.out.println(name);
}
context.close();
  • ConfigurationClassPostProcessor:解析@ComponentScan @Bean @Import @ImportResource
  • MapperScannerConfigurer:解析@Mapper
模拟实现组件扫描
  • 创建一个BeanFactoryPostProcessor的实现类
java 复制代码
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
        try {
            if (componentScan != null) {
                for (String basePackage : componentScan.basePackages()) {
                    System.out.println(basePackage);
                    String path = "classpath*:" + basePackage.replace(".", "/") + "/**/*.class";
                    System.out.println(path);
                    //用于获取元数据的工具类
                    CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
                    //用于生成bean名称的工具
                    AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
                    Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
                    for (Resource resource : resources) {
                        MetadataReader metadataReader = factory.getMetadataReader(resource);//根据resource获取元数据读取器
                        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//                    ClassMetadata classMetadata = metadataReader.getClassMetadata();
//                    System.out.println("类名:" + classMetadata.getClassName());
//                    //判读是否有注解@Component
//                    boolean hasComponent = metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName());
//                    System.out.println("包含注解Component:" + hasComponent);
//                    boolean hasMetaAnnotation = metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName());
//                    System.out.println("元注解中包含Component:"+hasMetaAnnotation);
                        if (annotationMetadata.hasAnnotation(Component.class.getName()) || annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
                            //构建beanDefinition对象
                            AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();
                            if (configurableListableBeanFactory instanceof DefaultListableBeanFactory) {
                                //获取容器
                                DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
                                //生成bean name
                                String name = generator.generateBeanName(bd, beanFactory);
                                //注册bean
                                beanFactory.registerBeanDefinition(name, bd);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 注册该后置处理器

    java 复制代码
    context.registerBean(ComponentScanPostProcessor.class);
模拟实现@Bean
java 复制代码
public class AtBeanPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        try {
            CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
            MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/vmware/a5/Config.class"));
            Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
            for (MethodMetadata method : methods) {
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
                //Bean的名称由方法名生成,除此之外还需要一个工厂Bean对象
                builder.setFactoryMethodOnBean(method.getMethodName(), "config");
                builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
                AbstractBeanDefinition bd = builder.getBeanDefinition();
                if (configurableListableBeanFactory instanceof DefaultListableBeanFactory) {
                    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
                    beanFactory.registerBeanDefinition(method.getMethodName(), bd);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
模拟实现Mapper扫描
java 复制代码
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
        try {
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources("classpath:com/vmware/a5/mapper/**/*.class");
            AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
            CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
            for (Resource resource : resources) {
                MetadataReader reader = factory.getMetadataReader(resource);
                //获取类元数据
                ClassMetadata classMetadata = reader.getClassMetadata();
                //过滤接口类型
                if (classMetadata.isInterface()){
                    AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
                            .addConstructorArgValue(classMetadata.getClassName())//构造方法需要对应的接口字节码
                            .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)//需要对MapperFactory进行注入
                            .getBeanDefinition();
                    //根据接口名称重新生成一个bean,仅用于生成mapper的名称,否则所有名称都是MapperFactoryBean
                    AbstractBeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
                    String name = generator.generateBeanName(bd2, beanFactory);
                    beanFactory.registerBeanDefinition(name,bd);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}
  • 将Mapper封装成MapperFactoryBean类型,然后注册到容器中
相关推荐
【D'accumulation】3 分钟前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
小叶学C++9 分钟前
【C++】类与对象(下)
java·开发语言·c++
2401_8543910812 分钟前
高效开发:SpringBoot网上租赁系统实现细节
java·spring boot·后端
Cikiss21 分钟前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
wxin_VXbishe22 分钟前
springboot合肥师范学院实习实训管理系统-计算机毕业设计源码31290
java·spring boot·python·spring·servlet·django·php
Cikiss23 分钟前
微服务实战——平台属性
java·数据库·后端·微服务
无敌の星仔31 分钟前
一个月学会Java 第2天 认识类与对象
java·开发语言
OEC小胖胖36 分钟前
Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)
java·spring boot·后端·spring·mybatis·web
2401_857617621 小时前
SpringBoot校园资料平台:开发与部署指南
java·spring boot·后端
quokka561 小时前
Springboot 整合 logback 日志框架
java·spring boot·logback