Spring底层原理(四)
本章内容
模拟实现Spring中的几个常见BeanFactory
后置处理器
常见的BeanFactory
后置处理器
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
的实现类
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {@Overridepublic 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 nameString name = generator.generateBeanName(bd, beanFactory);//注册beanbeanFactory.registerBeanDefinition(name, bd);}}}}}} catch (Exception e) {e.printStackTrace();}}
}
-
注册该后置处理器
context.registerBean(ComponentScanPostProcessor.class);
模拟实现@Bean
public class AtBeanPostProcessor implements BeanFactoryPostProcessor {@Overridepublic 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
扫描
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic 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的名称,否则所有名称都是MapperFactoryBeanAbstractBeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();String name = generator.generateBeanName(bd2, beanFactory);beanFactory.registerBeanDefinition(name,bd);}}}catch (Exception e){e.printStackTrace();}}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
}
- 将Mapper封装成
MapperFactoryBean
类型,然后注册到容器中