Spring扩展点ConfigurationClassPostProcessor
问题思考
- Spring在什么时候对@ComponentScan、@ComponentScans注解进行的解析?
- Spring在什么时候解析了@Import注解,如何解析的?
- Spring在什么时候解析了@Bean注解?
- Spring在什么时候加载的META-INF#spring.factories中的EnableAutoConfiguration类?
- @Configuration和@Component有什么区别?
上述这五个问题都和ConfigurationClassPostProcessor类有关
所以说ConfigurationClassPostProcessor是Spring中最重要的beanFactory后置处理器
大致执行流程如下图:
ConfigurationClassPostProcessor类签名、结构关系
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
//动态注册Bean到Spring容器(在bean实例化之前进一步注册bean definitions到BeanDefinitionMap中)
//BeanDefinitionRegistry其实就是BeanFactory的基础接口,包含registerBeanDefinition等一系列操作beanDefinition的方法
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
public interface BeanFactoryPostProcessor {
//beanFactory后置处理器的基础接口
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
- 可以看到ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,而BeanDefinitionRegistryPostProcessor接口又是继承了BeanFactoryPostProcessor接口。所以ConfigurationClassPostProcessor的主要功能逻辑都是围绕这两个接口展开的。
- BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry——动态注册Bean到Spring容器(在bean实例化之前进一步注册bean definitions到BeanDefinitionMap中)
- BeanFactoryPostProcessor#postProcessBeanFactory——beanFactory后置处理器的基础接口。在执行完postProcessBeanDefinitionRegistry方法再执行。
- 后面会详细介绍ConfigurationClassPostProcessor实现这两个接口方法的代码逻辑。
ConfigurationClassPostProcessor的注册时机
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
//......省略部分代码
// 创建容器上下文,执行Spring框架中的this();
context = createApplicationContext();
...省略
return context;
}
// 这里的DEFAULT_SERVLET_WEB_CONTEXT_CLASS是org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
...
}
// 实例化 AnnotationConfigServletWebServerApplicationContext
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
//AnnotationConfigServletWebServerApplicationContext的构造函数
public AnnotationConfigServletWebServerApplicationContext(){
//初始化读取注解的Bean定义读取器,并注册注解配置的的处理器(本节核心)
this.reader = new AnnotatedBeanDefinitionReader(this);
//初始化一个ClassPath类型的Bean的扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
// 在构造 AnnotatedBeanDefinitionReader时调用下面方法 注册下面五个内置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
//五个内置处理器
ConfigurationClassPostProcessor = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor" implements BeanDefinitionRegistryPostProcessor,PriorityOrdered
//解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
AutowiredAnnotationBeanPostProcessor = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor" implements BeanPostProcessor,PriorityOrdered
//解析@Autowired和@Value、@Inject注解
CommonAnnotationBeanPostProcessor = "org.springframework.context.annotation.internalCommonAnnotationProcessor" implements BeanPostProcessor
//处理@PostConstruct、@PreDestroy和@Resource注解
EventListenerMethodProcessor = "org.springframework.context.event.internalEventListenerProcessor" implements BeanFactoryPostProcessor
//处理@EventListener事件监听注解
DefaultEventListenerFactory = "org.springframework.context.event.internalEventListenerFactory"
//注册事件监听器工厂
//构造这五个内置处理器的具体方法位置:org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
ConfigurationClassPostProcessor的触发时机
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
...省略
// 刷新容器,注册bean
refreshContext(context);
...省略
return context;
}
AbstractApplicationContext下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备刷新上下文
prepareRefresh();
// 刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备BeanFactory
prepareBeanFactory(beanFactory);
try {
// 处理后置处理器,目前没有任何实现
postProcessBeanFactory(beanFactory);
/*
拿到所有自定义和内置的BeanDefinitionRegistryPostProcessor后置处理器,循环调用postProcessBeanDefinitionRegistry;
其中最重要的是ConfigurationClassPostProcessor处理器的执行:遍历BeanDefinition找到带有@Configuration注解的BeanDefinition,
解析处理配置类中的@Import,@PropertySources,@ComponentScans(如果存在注解,则会扫描对应路径的类转换成BeanDefinition,
存入BeanDefinitionMap),@Bean(同样)注解等 */
//本节核心逻辑
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor后置处理器
registerBeanPostProcessors(beanFactory);
// 初始化消息资源解析器
initMessageSource();
// 初始化注册一个单列ApplicationContext事件监听器applicationEventMulticaster
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊bean。交给子类实现
onRefresh();
//注册事件监听器,派发容器初始化的事件:监听器需要实现ApplicationListener接口
registerListeners();
// 实例所有的单例Bean,创建单例非懒加载的bean
finishBeanFactoryInitialization(beanFactory);
// 容器初始化完成,发布事件
finishRefresh();
}
catch (BeansException ex) {
// 销毁已经创建的单实例以避免悬空资源。
destroyBeans();
// 重置 'active' 标记
cancelRefresh(ex);
throw ex;
}
finally {
// 重置Spring核心的缓存
resetCommonCaches();
}
}
}
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
.....
// 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
.....
//执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
.....
}
ConfigurationClassPostProcessor的核心方法逻辑
postProcessBeanDefinitionRegistry();
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
...省略
// BeanDefinitionRegistryPostProcessor接口方法
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 循环解析配置类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//解析配置类 重点!!!
//candidates就是main方法所在的类,所以主入口就是解析启动类
//启动类上一般会包含很多@ComponentScan注解和@Import注解(@EnableXXX和@MapperScan都是符合注解,都包含了@Import注解)
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 将解析的配置类转成BeanDefinition加入BeanDefinitionMap中
// 扫描上面解析的配置类中的@Import、@Bean、
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
// 判断有没有添加新的BeanDefinition
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
// 如果有未解析的类,则将其添加到candidates中,这样candidates不为空,就会进入到下一次的while的循环中
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
}
parser.parse();
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// 如果bean实现自 AnnotatedBeanDefinition 接口,则进行注解bean定义的解析
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
// 如果bean实现自 AbstractBeanDefinition 接口,则进行抽象bean定义的解析
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
// 常规配置类进行解析
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
...
}
//当上述parse方法中@Import注解实现的接口是DeferredImportSelector,延迟到现在才执行处理真正逻辑
//主要处理之一就是加载解析spring.factories中的配置类
this.deferredImportSelectorHandler.process();
}
protected final void parse(Class<?> clazz, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
...判断是否已经解析过
...省略
// 获取源类
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 重点!!!
// 递归地处理配置类及其超类,返回值是configClass 的父类
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 记录已经解析的配置类
this.configurationClasses.put(configClass, configClass);
}
doProcessConfigurationClass();
@Nullable
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 递归处理内部类
processMemberClasses(configClass, sourceClass, filter);
}
// 处理 @PropertySource 资源文件
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 处理所有 @ComponentScan 注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 执行扫描 @ComponentScan 指定路径下所有 @Component
//
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 检查 ComponentScan 扫描得到的 BeanDefinition 定义,循环解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 递归解析
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 处理所有 @Import 注解,将 import 的bean变为 ConfigurationClass
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 处理所有 @ImportResource 注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 处理单个 @Bean 方法
// 此处只是将@Bean 方法添加到configClass的一个beanMethod属性中,还没有将其加入到BeanDefinitionMap中
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 处理接口默认方法
processInterfaces(configClass, sourceClass);
// 如果有父类,处理父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// 找到父类,返回
return sourceClass.getSuperClass();
}
}
return null;
}
processImports();
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
// 如果类上没有@Import 注解,直接返回
if (importCandidates.isEmpty()) {
return;
}
// 依赖检查
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
// 处理所有 @Import ,@Import存在三种情况
// ①:@Import的类实现了 ImportSelector 接口,实例化并执行 selectImports 方法
// ②:@Import的类实现了 DeferredImportSelector接口,实例化并延迟处理
// ③:@Import的类实现了 ImportBeanDefinitionRegistrar接口,实例化并加入 ImportBeanDefinitionRegistrars中后续处理
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
Class<?> candidateClass = candidate.loadClass();
// 实例化 ImportSelector
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
// 如果是实现 DeferredImportSelector ,则延迟处理
//主要是AutoConfigurationImportSelector这个类
//主要职责就是加载 spring.factories中的configuration 类
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
// 如果不是实现 DeferredImportSelector, 则执行 selectImports方法
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
// 递归继续处理, 被Import进来的类可能也有@Import注解
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
// 如果是实现 ImportBeanDefinitionRegistrar接口
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
Class<?> candidateClass = candidate.loadClass();
// 实例化 ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
// 加入 importBeanDefinitionRegistrars 中,后续处理configClass 时一并处理
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Import 普通类,则将其当作带有@Configuration的类一样处理
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
this.deferredImportSelectorHandler.process();
- 该方法的职责之一就是加载 spring.factories中的EnableAutoConfiguration类。方法调用路径简略记录如下:
- this.deferredImportSelectorHandler.process();
- handler.processGroupImports();
- grouping.getImports();
- AutoConfigurationImportSelector#this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector()); - ((AutoConfigurationImportSelector) deferredImportSelector).getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata);
- getCandidateConfigurations(annotationMetadata, attributes);
- SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
this.reader.loadBeanDefinitions(configClasses);
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
// 遍历加载配置文件的 BeanDefinition 到BeanDefinitionMap
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
...省略
if (configClass.isImported()) {
// 处理通过 @Import 方式导入的配置类
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 遍历处理配置类中 @Bean注解 的方法
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 处理通过 @ImportResource 方式导入的 XML配置类,(不详述)
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 处理实现 ImportBeanDefinitionRegistrar接口的配置类, 执行registerBeanDefinitions方法
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
postProcessBeanFactory();
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
// 因为ConfigurationClassPostProcessor 实现 BeanDefinitionRegistryPostProcessor
// 所以会先执行 postProcessBeanDefinitionRegistry, 而 postProcessBeanDefinitionRegistry 中又会执行 processConfigBeanDefinitions
// 所以此处为避免重复执行,不会执行
if (!this.registriesPostProcessed.contains(factoryId)) {
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
// 对加了@Configuration注解的配置类进行Cglib代理
enhanceConfigurationClasses(beanFactory);
// 添加 BeanPostProcessor 后置处理器:给 代理类添加 BeanFactory 属性
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
enhanceConfigurationClasses();
对加了@Configuration注解的配置类进行Cglib代理
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
// 为简略说明 改写了一下代码
if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
//非@Configuration注解的配置类,会在此处返回,不会进行下面Cglib代理增强
return;
}
...省略
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
...省略
// 创建 代理类
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
...省略
}
}
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
...省略
// 核心代码为 newEnHancer()
Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
...省略
return enhancedClass;
}
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
// CGLIB的动态代理基于继承
enhancer.setSuperclass(configSuperClass);
// 为新创建的代理对象设置一个父接口
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
// 添加回调方法, 每次代理对象的方法被调用时,都会先经过MethodInterceptor中的方法
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
- 可以看到当配置类是由@Configuration注解进行标识得,那么就会进行CGLIB代理增强,也就是该类所有方法都会被代理接管。需要注意的是,即使在方法中this调用另一个@Bean方法,但此时也是由代理对象去调用这另一个@Bean方法的,所以@Configuration配置类下的所有@Bean注解的方法多次调用返回的结果都是一致的(只执行一遍方法),返回的bean都是一个单例bean。
- 而如果是非@Configuration注解比如是@Component的话,那么由于没有进行CGLIB代理增强,也就没有代理对象进行额外逻辑处理(没有通过getBean找对象而是直接执行this调用)。所以该配置类下的@Bean注解的方法每次调用返回的结果都是不一致的,也就是返回的bean不是一个单例bean;
- 如果需要保持配置类下的@Bean是单例那就用@Configuration注解标记配置类;