🍅 作者简介:齐大,自学Java入门,现在某国企担任初级架构师
🍅 有自己独立的学习方法,以及适合大部分人的学习路线,面试架构思路等
🍅 关注公众号【齐疾行者Code】,查看最新最全的知识分享
Spring 的扩展点 是Spring易扩展的一个重要体现,熟悉这些扩展点的定义方式,以及其调用时机,不仅成为工作中利器,也能深度理解Spring框架的切入点。
BeanDefinitionRegistryPostProcessor接口的扩展点
BeanDefinitionRegistryPostProcessor用于对Bean定义的注册过程进行干预和定制。继承BeanFactoryPostProcessor接口,并在其基础上扩展了一个新的方法,即:postProcessBeanDefinitionRegistry()方法。
它提供了一种机制,允许开发人员在Bean定义注册之前和之后对Bean定义进行自定义处理。
编辑
来源
org.springframework.beans它是由Spring本身提供的容器级别的接口。
注:Bean定义与Bean实例化是不一样的
Bean定义:
Spring容器初始化时,从资源中读取到bean的相关定义后,保存在BeanDefinitionMap,这是将Spring管理的类封装为 BeanDefinition对象。
Bean实例化:
Spring通过扩展接口对BeanDefinition操作完成后,创建代理类的过程,是基于BeanDefinitionMap中的数据进行的 。
//所有Bean定义加载完成之后,Bean实例化之前被调用
//用来注册更多的bean到spring容器中
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
//继承自BeanFactoryPostProcessor接口的方法,用于在BeanFactory完成实例化之后对BeanFactory进行后置处理
//用来改变bean定义的
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
Spring内置实现类
-
PropertyResourceConfigurer 它抽象了容器BeanFactory后置处理阶段对容器中所有bean定义中的属性进行配置的一般逻辑,属性配置所使用的属性来源是基类PropertiesLoaderSupport方法所规定的那些属性。public abstract class PropertyResourceConfigurer extends PropertiesLoaderSupport implements BeanFactoryPostProcessor, PriorityOrdered { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { try { // 合并本地属性和外部指定的属性文件资源中的属性 Properties mergedProps = mergeProperties(); // 将属性的值做转换(仅在必要的时候做) convertProperties(mergedProps); // 对容器中的每个bean定义进行处理,也就是替换每个bean定义中的属性中的占位符 processProperties(beanFactory, mergedProps); } catch (IOException ex) { throw new BeanInitializationException("Could not load properties", ex); } } -
CustomAutowireConfigurer它允许您注册自己的自定义限定符(Qualifer)注解类型,即使它们没有使用Spring的@Qualifier注解进行注解。public class CustomAutowireConfigurer implements BeanFactoryPostProcessor, BeanClassLoaderAware, Ordered { ........ @Override @SuppressWarnings("unchecked") public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (this.customQualifierTypes != null) { if (!(beanFactory instanceof DefaultListableBeanFactory)) { throw new IllegalStateException( "CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory"); } DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory; if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) { dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); } QualifierAnnotationAutowireCandidateResolver resolver = (QualifierAnnotationAutowireCandidateResolver) dlbf.getAutowireCandidateResolver(); for (Object value : this.customQualifierTypes) { Class<? extends Annotation> customType = null; if (value instanceof Class) { customType = (Class<? extends Annotation>) value; } else if (value instanceof String) { String className = (String) value; customType = (Class<? extends Annotation>) ClassUtils.resolveClassName(className, this.beanClassLoader); } else { throw new IllegalArgumentException( "Invalid value [" + value + "] for custom qualifier type: needs to be Class or String."); } if (!Annotation.class.isAssignableFrom(customType)) { throw new IllegalArgumentException( "Qualifier type [" + customType.getName() + "] needs to be annotation type"); } resolver.addQualifierType(customType); } } } }
自定义实现方式
MyBeanDefinitionRegistryPostProcessor
-
在postProcessBeanDefinitionRegistry()方法被调用的时候手工在Spring中注册了Student类的BeanDefinition信息;
-
在postProcessBeanFactory()方法被调用的时候,从Spring容器中取出Dog类的BeanDefinition信息和Student类的实例;
@Data public class student{ private String name; private String age; }@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { //手工定义一个beanDefinition实例 RootBeanDefinition beanDefinition = new RootBeanDefinition(); //给beanDefinition填充属性 beanDefinition.setBeanClass(student.class); MutablePropertyValues propertyValues = new MutablePropertyValues(); PropertyValue propertyValue1 = new PropertyValue("name", "张三"); PropertyValue propertyValue2 = new PropertyValue("age", "11"); propertyValues.addPropertyValue(propertyValue1); propertyValues.addPropertyValue(propertyValue2); beanDefinition.setPropertyValues(propertyValues); //注册手工定义的beanDefinition registry.registerBeanDefinition("student", beanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("-----------postProcessBeanFactory start------------"); //根据类名取出手工注册的beanDefinition BeanDefinition beanDefinition = beanFactory.getBeanDefinition("student"); System.out.println(beanDefinition.getBeanClassName()); //根据类从容器中取出手工注册的beanDefinition所描述的实例bean Student student = beanFactory.getBean(Student.class); System.out.println(student.getName()); System.out.println(student.getAge()); System.out.println("-----------postProcessBeanFactory end------------"); }
初始化和执行时机
-
执行项目的主类org.springframework.boot.SpringApplication#run被调用;
-
执行到org.springframework.boot.SpringApplication#refreshContext,开始容器刷新,进入了核心调用链;
-
org.springframework.context.support.AbstractApplicationContext#refresh方法中进行容器刷新;
-
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors的方法中
开始初始化和执行实现BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry()和postProcessBeanFactory();
-
AbstractApplicationContext#invokeBeanFactoryPostProcessors的方法执行 org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors();
-
在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()方法中,并不是直接就初始化和执行postProcessBeanDefinitionRegistry()和postProcessBeanFactory(),而是又进行了一系列的判断,其判断顺序是:
(1):通过AbstractApplicationContext#addBeanFactoryPostProcessor提前注册的BeanDefinitionRegistryPostProcessor实现类
(2):实现了PriorityOrdered接口;
(3): 是否实现了Ordered;
(4): 剩下的其他BeanDefinitionRegistryPostProcessor实现类;
-
在执行完自定义的方法postProcessBeanDefinitionRegistry后,紧接着就开始执行
MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory方法了
关注公众号齐疾行者Code,获取更新更全的架构知识
架构のSpring扩展点(一):上下文创建前的动态处理-ApplicationContextInitializer
架构のSpring扩展点(二):Bean定义操作-BeanDefinitionRegistryPostProcessor
架构のSpring扩展点(三):Bean生命周期操作-InstantiationAwareBeanPostProcessor
架构のSpring扩展点(四):Bean初始化时对象自动注入-Aware全解析
架构のSpring扩展点(五):如何保证在同一线程内获取的bean是同一对象-自定义Scope
架构のSpring扩展点(六):ApplicationContextAwareProcessor接口全解析,看完就懂
架构のSpring扩展点(七):Java自带注解@postcontruct全解析,为什么不推荐使用?那什么时候可以使用了