文章目录
结论先行
扩展原理:
BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
1、BeanFactoryPostProcessor:beanFactory的后置处理器;
在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
BeanFactoryPostProcessor原理:
1)、ioc容器创建对象
2)、invokeBeanFactoryPostProcessors(beanFactory);
如何找到所有的BeanFactoryPostProcessor并执行他们的方法(postProcessBeanFactory);
1)、直接在BeanFactory中通过beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)这个方法找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
2)、在初始化创建/初始化其他组件(finishBeanFactoryInitialization(beanFactory)这个方法)前面执行
BeanFactoryPostProcessor子类
package com.ouyangxizhu.ext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
配置类
package com.ouyangxizhu.ext;
import com.ouyangxizhu.bean.Blue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan("com.ouyangxizhu.ext")
@Configuration
public class ExtConfig {
@Bean
public Blue blue(){
return new Blue();
}
}
启动类
package com.ouyangxizhu;
import com.ouyangxizhu.ext.ExtConfig;
import com.ouyangxizhu.tx.TxConfig;
import com.ouyangxizhu.tx.UserService;
import com.ouyangxizhu.utils.PrintBeanDefinitionNamesUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainTestExt {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ExtConfig.class);
PrintBeanDefinitionNamesUtils.printBeanNames(context);
}
}
工具类
package com.ouyangxizhu.utils;
import com.ouyangxizhu.config.MainConfigImport;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class PrintBeanDefinitionNamesUtils {
public static void printBeanNames(Class<?> clazz) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(clazz);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
System.out.println("===========");
System.out.println("共有" + beanDefinitionNames.length + "个bean");
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
public static void printBeanNames(AnnotationConfigApplicationContext context) {
String[] beanDefinitionNames = context.getBeanDefinitionNames();
System.out.println("===========");
System.out.println("共有" + beanDefinitionNames.length + "个bean");
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
结果
八月 07, 2020 7:02:56 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@377dca04: startup date [Fri Aug 07 19:02:56 CST 2020]; root of context hierarchy
MyBeanFactoryPostProcessor...postProcessBeanFactory...
当前BeanFactory中有9 个Bean
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extConfig, myBeanFactoryPostProcessor, blue]
八月 07, 2020 7:02:56 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
blue...constructor
=====================
===========
共有9个bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extConfig
myBeanFactoryPostProcessor
blue
结果解析
postProcessBeanFactory方法调用在类初始化之前,blue的定义在beanFactory中已经有了,但是还没初始化,接下来从这个类的方法定义中找解释和答案
BeanFactoryPostProcessor类的postProcessBeanFactory方法定义
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
/**
* Allows for custom modification of an application context's bean definitions,
* adapting the bean property values of the context's underlying bean factory.
*
* <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in
* their bean definitions and apply them before any other beans get created.
*
* <p>Useful for custom config files targeted at system administrators that
* override bean properties configured in the application context.
*
* <p>See PropertyResourceConfigurer and its concrete implementations
* for out-of-the-box solutions that address such configuration needs.
*
* <p>A BeanFactoryPostProcessor may interact with and modify bean
* definitions, but never bean instances. Doing so may cause premature bean
* instantiation, violating the container and causing unintended side-effects.
* If bean instance interaction is required, consider implementing
* {@link BeanPostProcessor} instead.
*
* @author Juergen Hoeller
* @since 06.07.2003
* @see BeanPostProcessor
* @see PropertyResourceConfigurer
*/
public interface BeanFactoryPostProcessor {
/**
*在bean factory标准初始化之后修改IOC容器中的内部bean factory
* Modify the application context's internal bean factory after its standard
* //所有的bean定义已经被加载了,但是没有bean被实例化
* 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;
}