公司网站制作要多少钱,百度收录什么意思,网站建设团队管理怎么写,哪个网站做ppt简单回顾一下上一篇文章#xff0c;是在BeanFacroty创建完之后#xff0c;可以通过Editor和EditorRegistrar实现对类属性的自定义扩展#xff0c;以及忽略要自动装配的Aware接口。 本篇帖子会顺着refresh()主流程方法接着向下执行。在讲invokeBeanFactoryPostProcessors方法…简单回顾一下上一篇文章是在BeanFacroty创建完之后可以通过Editor和EditorRegistrar实现对类属性的自定义扩展以及忽略要自动装配的Aware接口。 本篇帖子会顺着refresh()主流程方法接着向下执行。在讲invokeBeanFactoryPostProcessors方法的具体逻辑之前先简单介绍BeanFactoryPostProcessor接口和整个invokeBeanFactoryPostProcessors方法的执行流程。
refresh
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing./*** 前戏做容器刷新前的准备工作* 1、设置容器的启动时间* 2、设置活跃状态为true* 3、设置关闭状态为false* 4、获取Environment对象并加载当前系统的属性值到Environment对象中* 5、准备监听器和事件的集合对象默认为空的集合*/prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 创建容器对象DefaultListableBeanFactory// 加载xml配置文件的属性值到当前工厂中最重要的就是BeanDefinitionConfigurableListableBeanFactory beanFactory obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// beanFactory的准备工作对各种属性进行填充prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 子类覆盖方法做额外的处理此处我们自己一般不做任何扩展工作但是可以查看web中的代码是有具体实现的postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.// 调用各种beanFactory处理器invokeBeanFactoryPostProcessors(beanFactory);} }}FunctionalInterface
public interface BeanFactoryPostProcessor {/*** Modify the application contexts internal bean factory after its standard* initialization. All bean definitions will have been loaded, but no beans* will have been instantiated yet. This allows for overriding or adding* properties even to eager-initializing beans.* param beanFactory the bean factory used by the application context* throws org.springframework.beans.BeansException in case of errors*/void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {/*** Modify the application contexts internal bean definition registry after its* standard initialization. All regular bean definitions will have been loaded,* but no beans will have been instantiated yet. This allows for adding further* bean definitions before the next post-processing phase kicks in.* param registry the bean definition registry used by the application context* throws org.springframework.beans.BeansException in case of errors*/void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}BFPP和BDRPP
根据上面的流程图以及代码块可以看出BFPP和BDRPP的关系其中BFPP类中只有一个postProcessBeanFactory()方法而BDRPP中只有postProcessBeanDefinitionRegistry()方法因为是继承的关系所以所有实现BDRPP接口的类也会有postProcessBeanFactory()方法。 而BFPP和BDRPP其中有一个很重要的区别就在于它们两个方法接收的参数不同其中BFPP接收BeanFactory参数针对整个BeanFactory做操作而BDRPP接收的参数是BeanDefinitionRegistry可以理解是对Definition做一些正删改查的操作。
BeanDefinitionRegistry
public interface BeanDefinitionRegistry extends AliasRegistry {/*** 注册BeanDefinition到注册表** Register a new bean definition with this registry.* Must support RootBeanDefinition and ChildBeanDefinition.* param beanName the name of the bean instance to register* param beanDefinition definition of the bean instance to register* throws BeanDefinitionStoreException if the BeanDefinition is invalid* throws BeanDefinitionOverrideException if there is already a BeanDefinition* for the specified bean name and we are not allowed to override it* see GenericBeanDefinition* see RootBeanDefinition* see ChildBeanDefinition*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;/*** 移除注册表中beanName的BeanDefinition** Remove the BeanDefinition for the given name.* param beanName the name of the bean instance to register* throws NoSuchBeanDefinitionException if there is no such bean definition*/void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** 获取注册表中beanName的BeanDefinition** Return the BeanDefinition for the given bean name.* param beanName name of the bean to find a definition for* return the BeanDefinition for the given name (never {code null})* throws NoSuchBeanDefinitionException if there is no such bean definition*/BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** 检查此注册表是否包含具有给定名称的BeanDefinition** Check if this registry contains a bean definition with the given name.* param beanName the name of the bean to look for* return if this registry contains a bean definition with the given name*/boolean containsBeanDefinition(String beanName);/*** 返回此注册表中定义的所有bean的名称** Return the names of all beans defined in this registry.* return the names of all beans defined in this registry,* or an empty array if none defined*/String[] getBeanDefinitionNames();/*** 返回注册表中定义的bean的数目** Return the number of beans defined in the registry.* return the number of beans defined in the registry*/int getBeanDefinitionCount();/*** 确定给定bean名称是否已在该注册表中使用** Determine whether the given bean name is already in use within this registry,* i.e. whether there is a local bean or alias registered under this name.* param beanName the name to check* return whether the given bean name is already in use*/boolean isBeanNameInUse(String beanName);}接口的作用和整体的执行流程已经介绍完成下面看看invokeBeanFactoryPostProcessors方法的具体执行逻辑。
invokeBeanFactoryPostProcessors
主要是调用delegate中的同名invokeBeanFactoryPostProcessors方法对BaenFactory中和自定义注册进来的BFPP的实现类进行处理。 其中getBeanFactoryPostProcessors()是如果类继承了AbstractApplicationContext后可以有add方法自行注册BeanFactoryPostProcessor。处理时也会先处理这部分的BFPP。
invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 获取到当前应用程序上下文的beanFactoryPostProcessors变量的值并且实例化调用执行所有已经注册的beanFactoryPostProcessor// 默认情况下通过getBeanFactoryPostProcessors()来获取已经注册的BFPP但是默认是空的PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantimeif (beanFactory.getTempClassLoader() null beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}AbstractApplicationContext 如果想要自己注册进来要实现AbstractApplicationContext并调用addBeanFactoryPostProcessor方法将自定义BFPP实现类加进来就可以get到。
public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext {Overridepublic void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {this.beanFactoryPostProcessors.add(postProcessor);}/*** Return the list of BeanFactoryPostProcessors that will get applied* to the internal BeanFactory.*/public ListBeanFactoryPostProcessor getBeanFactoryPostProcessors() {return this.beanFactoryPostProcessors;}//删除其他代码
} 具体处理逻辑 如最开始图片中标注的处理流程一样
处理过的BFPP都放入processedBeans集合避免后续重复执行。先遍历beanFactoryPostProcessors中BDRPP类型的并直接调用postProcessBeanDefinitionRegistry进行逻辑处理。非BDRPP类型放入regularPostProcessors集合后续统一处理。找到BeanFactory中BDRPP类型并根据PriorityOrderedOrder进行优先级排序最后再执行没有优先级的。因为继承了BDRPP的肯定也会有BFPP中的方法所以还会统一处理执行BDRPP中的postProcessBeanFactory方法。执行完BeanFactory中的BDRPP类型后再查找BeanFactory中BFPP类型同样按照PriorityOrderedOrder进行优先级排序。并执行postProcessBeanFactory方法。
class PostProcessorRegistrationDelegate {public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListBeanFactoryPostProcessor beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.//所有已经执行过BFPP的存储在processedBeans防止重复执行SetString processedBeans new HashSetString();//判断beanFactory是否属于BeanDefinitionRegistry类型默认的beanFactory是DefaultListableBeanFactory//实现了BeanDefinitionRegistry 所以为trueif (beanFactory instanceof BeanDefinitionRegistry) {//强制类型转换BeanDefinitionRegistry registry (BeanDefinitionRegistry) beanFactory;//存放BFPP类型的集合ListBeanFactoryPostProcessor regularPostProcessors new LinkedListBeanFactoryPostProcessor();//存放BDRPP类型的集合ListBeanDefinitionRegistryPostProcessor registryPostProcessors new LinkedListBeanDefinitionRegistryPostProcessor();//优先处理入参中的beanFactoryPostProcessors,遍历所有beanFactoryPostProcessors//并将参数中的BFPP和BDRPP区分开for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {//如果是BDRPP类型if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryPostProcessor (BeanDefinitionRegistryPostProcessor) postProcessor;//直接调用BDRPP中的postProcessBeanDefinitionRegistry具体方法进行处理registryPostProcessor.postProcessBeanDefinitionRegistry(registry);//放入registryPostProcessors集合中registryPostProcessors.add(registryPostProcessor);}else {//否则只是普通的BeanFactoryPostProcessor则放入regularPostProcessors集合regularPostProcessors.add(postProcessor);}}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// Separate between BeanDefinitionRegistryPostProcessors that implement// PriorityOrdered, Ordered, and the rest.//根据type获取BeanFactory中所有类型为BDRPP的postProcessorNamesString[] postProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.//将实现了BDRPP和priorityOrder接口的类放入该集合ListBeanDefinitionRegistryPostProcessor priorityOrderedPostProcessors new ArrayListBeanDefinitionRegistryPostProcessor();for (String ppName : postProcessorNames) {//如果是PriorityOrdered类型的if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//放入priorityOrderedPostProcessors集合priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//放入processedBeans集合避免重复执行processedBeans.add(ppName);}}//按照优先级进行排序OrderComparator.sort(priorityOrderedPostProcessors);//添加到registryPostProcessors中registryPostProcessors.addAll(priorityOrderedPostProcessors);//遍历priorityOrderedPostProcessors集合执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.//再次获取BDRPP类型的所有postProcessorNamespostProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//实现了Order接口的BeanDefinitionRegistryPostProcessor放入该集合ListBeanDefinitionRegistryPostProcessor orderedPostProcessors new ArrayListBeanDefinitionRegistryPostProcessor();for (String ppName : postProcessorNames) {//如果是没执行过并且实现了Order接口的if (!processedBeans.contains(ppName) beanFactory.isTypeMatch(ppName, Ordered.class)) {//放到Order集合中orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//放入processedBeans集合避免重复执行processedBeans.add(ppName);}}//按照优先级排序OrderComparator.sort(orderedPostProcessors);//放入registryPostProcessors集合registryPostProcessors.addAll(orderedPostProcessors);//遍历orderedPostProcessors集合执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.boolean reiterate true;while (reiterate) {reiterate false;//找出所有实现了BDRPP接口的类postProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {//跳过执行过BDRPP的类if (!processedBeans.contains(ppName)) {//根据name获取实例BeanDefinitionRegistryPostProcessor pp beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);//添加到registryPostProcessors集合中registryPostProcessors.add(pp);//添加到processedBeans集合中processedBeans.add(ppName);//直接执行BDRPPpp.postProcessBeanDefinitionRegistry(registry);reiterate true;}}} // Now, invoke the postProcessBeanFactory callback of all processors handled so far.//遍历registryPostProcessors和regularPostProcessors中有所的bean//执行BFPP接口postProcessBeanFactory方法invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}//如果beanFactory不属于BeanDefinitionRegistry直接执行具体方法else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}//到这为止入参的beanFactoryPostProcessors和BeanFactory中BDRPP类型的方法已经全部处理完成//后面开始都是操作BFPP类型//到这位置// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!//找到所有实现BeanFactoryPostProcessor的类String[] postProcessorNames beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.//依次声明priorityOrderedPostProcessors、orderedPostProcessorNames和nonOrderedPostProcessorNames分别用来存放对应//实现了priorityOrdered、ordered和没实现排序接口的类ListBeanFactoryPostProcessor priorityOrderedPostProcessors new ArrayListBeanFactoryPostProcessor();ListString orderedPostProcessorNames new ArrayListString();ListString nonOrderedPostProcessorNames new ArrayListString();//遍历所有postProcessorNames将没执行过的BFPP方法的类放入对应集合中。for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.//按照优先级进行排序并执行具体的BFPP方法OrderComparator.sort(priorityOrderedPostProcessors);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.ListBeanFactoryPostProcessor orderedPostProcessors new ArrayListBeanFactoryPostProcessor();for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}OrderComparator.sort(orderedPostProcessors);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.ListBeanFactoryPostProcessor nonOrderedPostProcessors new ArrayListBeanFactoryPostProcessor();for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);}看完上面这段源码之后不知道大家有没有这样的一个疑问为什么重复代码较多每次都要根据类型重新获取String[] postProcessorNames第一次获取后根据postProcessorNames按照PriorityOrdered和Order进行优先级排序、分组执行不行么 是因为在执行BDRPP的方法postProcessBeanDefinitionRegistry时有可能会有新增的额外的BDRPP的类每次都重新获取能避免BDRPP类执行的不完全。