Spring原始碼解析之BeanPostProcessor
前言
AbstractApplicationContext類
refresh()方法
spring在bean的註冊與例項化之間會出現如下程式碼
//bean的註冊 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //1. Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); //2. Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); //3. Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); //bean的例項化 finishBeanFactoryInitialization(beanFactory);
1.在AbstractApplicationContext為一個空方法,其子類對該方法進行了重寫
2.BeanDefinitionRegistryPostProcessor與BeanFactoryPostProcessor介面的呼叫
3.把實現了BeanPostProcessor介面的類例項化,並且加入到BeanFactory中
invokeBeanFactoryPostProcessors()的原始碼分析
看個例子
BeanDefinitionTest類
@Component public class BeanDefinitionTest implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition(); genericBeanDefinition.setBeanClass(BeanClass.class); MutablePropertyValues propertyValues = genericBeanDefinition.getPropertyValues(); propertyValues.addPropertyValue("username", "蔡徐坤"); beanDefinitionRegistry.registerBeanDefinition("beanClass", genericBeanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { BeanClass beanClass = (BeanClass) configurableListableBeanFactory.getBean("beanClass"); System.out.println("postProcessBeanFactory="+beanClass.getUsername()); } }
BeanClass類
@Data
public class BeanClass {
private String username;
}
測試方法
@Test public void test5() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("cn.com.dq"); BeanClass beanClass = (BeanClass) applicationContext.getBean("beanClass"); System.out.println(beanClass.getUsername()); }
結果輸出
從上述例子我們來看invokeBeanFactoryPostProcessors()的原始碼
PostProcessorRegistrationDelegate類
invokeBeanFactoryPostProcessors()方法
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
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.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//獲取實現了BeanDefinitionRegistryPostProcessor介面的所有類的BeanDefinition物件的beanName
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判斷是否實現了排序介面 PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//呼叫過程
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判斷是否是實現的Ordered介面
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
//沒實現排序介面的呼叫
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//呼叫postProcessBeanFactory方法
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//獲取實現了BeanFactoryPostProcessor介面的類,獲取beanDefinition的名稱
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//實現了PriorityOrdered介面的
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//實現了Ordered介面的
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
//沒實現介面的
nonOrderedPostProcessorNames.add(ppName);
}
}
//排序
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//呼叫
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
上述程式碼執行過程:
1.獲取所有實現BeanDefinitionRegistryPostProcessor介面的beanName
2.注意這行程式碼
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
我們知道beanFactory.getBean()是bean的例項化,這裡是優先將實現BeanDefinitionRegistryPostProcessor介面的bean進行例項化,然後加入到currentRegistryProcessors容器中
3.接下來執行了這行程式碼
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
我們可以看到最終是執行了BeanDefinitionRegistryPostProcessor 介面的postProcessBeanDefinitionRegistry方法
4.我們回過來看我們寫的demo類
我們在postProcessBeanDefinitionRegistry方法中重新註冊了一個我們新建立的bean叫做beanClass,並且給beanClass裡的屬性賦值了蔡徐坤
5.執行完所有的有關BeanDefinitionRegistryPostProcessor 介面的postProcessBeanDefinitionRegistry方法呼叫後
接著呼叫瞭如下程式碼
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
從上面可以看出 是執行了BeanDefinitionRegistryPostProcessor 介面的postProcessBeanFactory方法
BeanDefinitionRegistryPostProcessor介面繼承了BeanFactoryPostProcessor介面,postProcessBeanFactory方法為
BeanFactoryPostProcessor中的方法
6.回到demo
我們在這個方法中通過getBean操作例項化了beanClass然後列印了該例項中的屬性,因此能解釋我們寫的demo控制檯的輸出
7.通過與BeanDefinitionRegistryPostProcessor 相同的方式,處理了實現BeanFactoryPostProcessor介面的bean的postProcessBeanFactory方法的呼叫
registerBeanPostProcessors方法的原始碼分析
PostProcessorRegistrationDelegate類
registerBeanPostProcessors方法
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//拿到工程裡面所有實現了BeanPostProcessor介面的類,獲取到BeanDefinition的名稱
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//提前例項化BeanPostProcessor型別的bean,然後bean進行排序
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//getBean是例項化方法,後面我們在講bean例項化過程
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
//判斷型別是否是MergedBeanDefinitionPostProcessor,如果是則程式碼是內部使用的
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//註冊到BeanFactory中
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
1.拿到工程裡面所有實現了BeanPostProcessor介面的類,獲取到BeanDefinition的名稱
2.遍歷所有的beanName,在迴圈中,我們看到一個比較重要的程式碼
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
我們知道beanFactory.getBean()是bean的例項化,所以,我們可以得到spring容器在例項化bean的時候,優先例項化的是BeanPostProcessor型別的bean,為什麼要優先例項化BeanPostProcessor型別的bean,因為其他bean的例項化需要呼叫BeanPostProcessor裡面的方法
3.例項化BeanPostProcessor型別的bean以後,接下來會將這些bean註冊到beanFactory的beanPostProcessors容器中
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
AbstractBeanFactory類
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
這裡有一個比較有意思的變數hasInstantiationAwareBeanPostProcessors ,在bean例項化的時候,會利用到這個變數
在bean例項化的時候會解釋這個變數的作用
總結
1.invokeBeanFactoryPostProcessors方法首先是對實現了BeanDefinitionRegistryPostProcessor介面的bean進行了例項化,接著對BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法進行了呼叫,然後對BeanDefinitionRegistryPostProcessor中的 postProcessBeanFactory方法進行了呼叫
2.invokeBeanFactoryPostProcessors 接下來對實現了BeanFactoryPostProcessor介面的bean進行了例項化,然後對BeanFactoryPostProcessor中的postProcessBeanFactory方法進行了呼叫
3.registerBeanPostProcessors()提前對所有實現了BeanPostProcessor 介面的bean進行例項化,然後將這些bean註冊到beanFactory的beanPostProcessors容器中
4.spring在bean的例項化過程中,優先例項化的是實現了BeanDefinitionRegistryPostProcessor的bean,其次是實現了
BeanFactoryPostProcessor介面的bean,再次是實現了BeanPostProcessor 介面的bean,最後是普通bean