spring源码阅读-- 容器启动之BeanFactoryPostProcessor
Posted hanjiehu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring源码阅读-- 容器启动之BeanFactoryPostProcessor相关的知识,希望对你有一定的参考价值。
接着上文《spring源码阅读(2)-- 容器启动之加载BeanDefinition》,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置beanFactory,例如设置一下装配规则和判断是否需要创建一些指定的bean。
1 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { 2 // Tell the internal bean factory to use the context‘s class loader etc. 3 beanFactory.setBeanClassLoader(getClassLoader()); 4 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); 5 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); 6 7 // Configure the bean factory with context callbacks. 8 //添加ApplicationContextAwareProcessor用于处理实现了EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware接口的bean 9 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 10 //忽略以下bean的依赖注入 11 beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); 12 beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); 13 beanFactory.ignoreDependencyInterface(MessageSourceAware.class); 14 beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); 15 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); 16 17 // BeanFactory interface not registered as resolvable type in a plain factory. 18 // MessageSource registered (and found for autowiring) as a bean. 19 //注册自动装配模式下的特殊依赖,例如被注入的是BeanFactory类型,那么注入的就是beanFactory 20 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); 21 beanFactory.registerResolvableDependency(ResourceLoader.class, this); 22 beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); 23 beanFactory.registerResolvableDependency(ApplicationContext.class, this); 24 25 // Detect a LoadTimeWeaver and prepare for weaving, if found. 26 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 27 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 28 // Set a temporary ClassLoader for type matching. 29 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 30 } 31 32 // Register default environment beans. 33 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { 34 beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); 35 } 36 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { 37 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); 38 } 39 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { 40 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); 41 } 42 }
当设置完beanFactory,接下来就是执行BeanFactoryPostProcessor。BeanFactoryPostProcessor是spring容器启动时暴露给用户的一个扩展点,允许用户在spring创建bean之前做修改或动态添加bean,动态注册bean可以使用BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor。BeanFactoryPostProcessor接口定义如下:
1 public interface BeanFactoryPostProcessor { 2 3 void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; 4 5 }
当我们实现了BeanFactoryPostProcessor,spring是怎么去执行的呢?
spring容器在执行刷新时,当加载完BeanDefinition和配置好beanFactory时,会进入AbstractApplicationContext.invokeBeanFactoryPostProcessors,方法里首先调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors去执行实现了BeanFactoryPostProcessor的postProcessBeanFactory方法,然后再判断是否新添加了loadTimeWeaver这个bean,如果有,添加LoadTimeWeaverAwareProcessor
1 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { 2 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 3 4 // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime 5 // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) 6 if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 7 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 8 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 9 } 10 }
进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,方法里首先判断beanFactory是不是一个bean注册中心,如果是,循环遍历传入的BeanFactoryPostProcessor,判断是否是BeanDefinitionRegistryPostProcessor的实现,如果是,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry,然后保存到一个集合用于在执行完所有的BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法之后,再执行BeanFactoryPostProcessor.postProcessBeanFactory。
1 public static void invokeBeanFactoryPostProcessors( 2 ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { 3 4 // Invoke BeanDefinitionRegistryPostProcessors first, if any. 5 Set<String> processedBeans = new HashSet<String>(); 6 7 if (beanFactory instanceof BeanDefinitionRegistry) { 8 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; 9 List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>(); 10 List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = 11 new LinkedList<BeanDefinitionRegistryPostProcessor>(); 12 13 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { 14 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { 15 BeanDefinitionRegistryPostProcessor registryPostProcessor = 16 (BeanDefinitionRegistryPostProcessor) postProcessor; 17 registryPostProcessor.postProcessBeanDefinitionRegistry(registry); 18 registryPostProcessors.add(registryPostProcessor); 19 } 20 else { 21 regularPostProcessors.add(postProcessor); 22 } 23 } 24 25 // Do not initialize FactoryBeans here: We need to leave all regular beans 26 // uninitialized to let the bean factory post-processors apply to them! 27 // Separate between BeanDefinitionRegistryPostProcessors that implement 28 // PriorityOrdered, Ordered, and the rest. 29 String[] postProcessorNames = 30 beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 31 32 // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. 33 List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); 34 for (String ppName : postProcessorNames) { 35 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 36 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 37 processedBeans.add(ppName); 38 } 39 } 40 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); 41 registryPostProcessors.addAll(priorityOrderedPostProcessors); 42 invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); 43 44 // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. 45 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 46 List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); 47 for (String ppName : postProcessorNames) { 48 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { 49 orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 50 processedBeans.add(ppName); 51 } 52 } 53 sortPostProcessors(beanFactory, orderedPostProcessors); 54 registryPostProcessors.addAll(orderedPostProcessors); 55 invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); 56 57 // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. 58 boolean reiterate = true; 59 while (reiterate) { 60 reiterate = false; 61 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 62 for (String ppName : postProcessorNames) { 63 if (!processedBeans.contains(ppName)) { 64 BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class); 65 registryPostProcessors.add(pp); 66 processedBeans.add(ppName); 67 pp.postProcessBeanDefinitionRegistry(registry); 68 reiterate = true; 69 } 70 } 71 } 72 73 // Now, invoke the postProcessBeanFactory callback of all processors handled so far. 74 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); 75 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); 76 } 77 78 else { 79 // Invoke factory processors registered with the context instance. 80 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); 81 } 82 83 // Do not initialize FactoryBeans here: We need to leave all regular beans 84 // uninitialized to let the bean factory post-processors apply to them! 85 String[] postProcessorNames = 86 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); 87 88 // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, 89 // Ordered, and the rest. 90 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 91 List<String> orderedPostProcessorNames = new ArrayList<String>(); 92 List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); 93 for (String ppName : postProcessorNames) { 94 if (processedBeans.contains(ppName)) { 95 // skip - already processed in first phase above 96 } 97 else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 98 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); 99 } 100 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 101 orderedPostProcessorNames.add(ppName); 102 } 103 else { 104 nonOrderedPostProcessorNames.add(ppName); 105 } 106 } 107 108 // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. 109 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); 110 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); 111 112 // Next, invoke the BeanFactoryPostProcessors that implement Ordered. 113 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 114 for (String postProcessorName : orderedPostProcessorNames) { 115 orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 116 } 117 sortPostProcessors(beanFactory, orderedPostProcessors); 118 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); 119 120 // Finally, invoke all other BeanFactoryPostProcessors. 121 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 122 for (String postProcessorName : nonOrderedPostProcessorNames) { 123 nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 124 } 125 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); 126 127 // Clear cached merged bean definitions since the post-processors might have 128 // modified the original metadata, e.g. replacing placeholders in values... 129 beanFactory.clearMetadataCache(); 130 }
invokeBeanFactoryPostProcessors方法里会找出所有的bean,先排序然后再执行相应的方法。从源码可以看得出,先执行的是传进来的BeanFactoryPostProcessor,第二是实现了PriorityOrdered的接口,第三是实现了Ordered接口,最后的就是没有指定顺序的,而实现了BeanDefinitionRegistryPostProcessor的,会先执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。
至此,spring对BeanFactoryPostProcessor的扩展点已处理完,从源码可以开出,BeanFactoryPostProcessor的处理会触发bean的创建。
以上是关于spring源码阅读-- 容器启动之BeanFactoryPostProcessor的主要内容,如果未能解决你的问题,请参考以下文章
spring源码阅读-- 容器启动之加载BeanDefinition
Spring源码阅读之Springs-beans容器的基本实现
Spring源码阅读Spring容器启动原理(上)-配置资源加载和注册