public User() {
System.out.println(“User对象”);
}
}
public class User2 {
public User2() {
System.out.println(“User2对象”);
}
}
这是一个最简单的spring项目,在配置类中有@Configuration注解,我们运行启动类,可以看到如下打印信息:
image-20210115101414931
如果去掉配置类中的@Configuration注解会怎样呢,去掉之后,咱们来看看打印信息:
image-20210115101618212
分析:
- 在上面的代码中,并没有直接调用配置类和实体类,说明这些都在spring底层进行了封装
- 在配置类中User类是进行了两次实例化的,但加了@Configuration注解后,只进行一次实例化,说明@Configuration注解将@Bean的方法进行的增强,保证实例为单实例
2. 问题
问1:@Configuration注解是如何定义bean之间的依赖关系?
问2:@Configuration注解是如何将@Bean方法进行增强的?
下面将跟踪spring源码来回答这两个问题
三、源码追踪
启动类代码只有AnnotationConfigApplicationContext
类,所以咱们以这里为入口,点进去可以看到源码如下:
public AnnotationConfigApplicationContext(Class<?>… componentClasses) {
this();
this.register(componentClasses);
this.refresh();
}
在这段源码中
-
this()
:这个无参构造是和bean相关的 -
register(componentClasses)
:将componentClasses注册到beanDefinitionMap集合中去 -
refresh()
:和@Configuration注解相关
所以咱们跟踪refresh()
,点进去查看源码:
【AbstractApplicationContext
类中refresh
方法】
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start(“spring.context.refresh”);
this.prepareRefresh();
// 告诉子类加载内部bean工厂
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 准备在上下文中使用的bean工厂
this.prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后置处理
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start(“spring.context.beans.post-process”);
// 这个方法是源码分析里面比较重要的一个入口,这里只讲和@Configuration注解相关的
// 解析@Configuration配置类,将自定义的BeanFactoryPostProcessor、BeanPostProcessor注册到beanDefinitionMap
this.invokeBeanFactoryPostProcessors(beanFactory);
// 将BeanPostProcessor实例化成bean并注册到beanFactory的beanPostProcessors
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 注册国际化相关的Bean
this.initMessageSource();
// 为上下文注册应用事件广播器(用于ApplicationEvent的广播),如果有自定义则使用自定义的,如果没有则内部实例化一个
this.initApplicationEventMulticaster();
this.onRefresh();
// 注册所有(静态、动态)的listener,并广播earlyApplicationEvents
this.registerListeners();
// 实例化用户自定义的普通单例Bean
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
// 销毁已经创建的单例,以避免悬浮资源
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
// 在Spring的核心中重置公共缓存
this.resetCommonCaches();
contextRefresh.end();
}
}
}
上面的源码给出了部分注释,我们可以看到,和@Configuration注解相关的是invokeBeanFactoryPostProcessors
方法,咱们继续跟踪,点进去看源码:
【AbstractApplicationContext
类中invokeBeanFactoryPostProcessors
方法】
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
// invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(“loadTimeWeaver”)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
继续跟踪invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors())
,进入源码查看:
【PostProcessorRegistrationDelegate
中invokeBeanFactoryPostProcessors
方法】
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
Set processedBeans = new HashSet();
ArrayList regularPostProcessors;
ArrayList registryProcessors;
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
// 判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
// 用于存放普通的BeanFactoryPostProcessor
regularPostProcessors = new ArrayList();
// 用于存放BeanDefinitionRegistryPostProcessor
registryProcessors = new ArrayList();
Iterator var6 = beanFactoryPostProcessors.iterator();
// 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
currentRegistryProcessors = new ArrayList();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var16 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
// 遍历postProcessorNames
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 解析配置类,为配置中的bean定义生成对应beanDefinition,并注入到registry的beanDefinitionMap
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var16 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var19 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var26 = 0; var26 < var10; ++var26) {
String ppName = var19[var26];
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// 调用ConfigurationClassPostProcessor#postProcessBeanFactory增强配置类
// 通过cglib生成增强类,加载到jvm内存
// 设置beanDefinition的beanClass为增强类,让@Bean生成的bean是单例
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var20 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var20; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
registryProcessors.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(regularPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List orderedPostProcessors = new ArrayList(registryProcessors.size());
Iterator var21 = registryProcessors.iterator();
while(var21.hasNext()) {
String postProcessorName = (String)var21.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());
Iterator var24 = currentRegistryProcessors.iterator();
while(var24.hasNext()) {
ppName = (String)var24.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
这里和@Configuration注解相关的方法是invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
,继续跟踪,进入源码查看:
【PostProcessorRegistrationDelegate
中invokeBeanFactoryPostProcessors
方法】
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
StartupStep var10000 = beanFactory.getApplicationStartup().start(“spring.context.bean-factory.post-process”);
postProcessor.getClass();
StartupStep postProcessBeanFactory = var10000.tag(“postProcessor”, postProcessor::toString);
// 调用ConfigurationClassPostProcessor#postProcessBeanFactory增强配置类
postProcessor.postProcessBeanFactory(beanFactory);
postProcessBeanFactory.end();
}
}
继续跟踪postProcessor.postProcessBeanFactory(beanFactory);
,进入源码查看,发现是一个接口,咱们找到和@Configuration相关的,也就是截图中框出来的 ,查看源码:
image-20210115154241215
【ConfigurationClassPostProcessor
类中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);
} else {
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
this.processConfigBeanDefinitions((BeanDefinitionRegistry)beanFactory);
}
// 进行代理,为@Configuration注解的类生成增强类
this.enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor(beanFactory));
}
}
该方法会去判断我们的bean工厂当中是否有bean需要进行cglib代理,并在enhanceConfigurationClasses(beanFactory)
方法中进行代理,为@Configuration注解的类生成增强类,继续跟踪,点进enhanceConfigurationClasses
,如下:
【ConfigurationClassPostProcessor
类中enhanceConfigurationClasses
方法】
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
StartupStep enhanceConfigClasses = this.applicationStartup.start(“spring.context.config-classes.enhance”);
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap();
String[] var4 = beanFactory.getBeanDefinitionNames();
int var5 = var4.length;
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
// 在ConfigurationClassUtils中标记是Full @Configuration还是lite @Bean mode
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
MethodMetadata methodMetadata = null;
if (beanDef instanceof AnnotatedBeanDefinition) {
methodMetadata = ((AnnotatedBeanDefinition)beanDef).getFactoryMethodMetadata();
}
if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
AbstractBeanDefinition abd = (AbstractBeanDefinition)beanDef;
if (!abd.hasBeanClass()) {
try {
abd.resolveBeanClass(this.beanClassLoader);
} catch (Throwable var13) {
throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), var13);
}
}
}
// 1.判断是否是全类注解
if (“full”.equals(configClassAttr)) {
if (!(beanDef instanceof AbstractBeanDefinition)) {
throw new BeanDefinitionStoreException(“Cannot enhance @Configuration bean definition '” + beanName + “’ since it is not stored in an AbstractBeanDefinition subclass”);
}
if (this.logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
this.logger.info(“Cannot enhance @Configuration bean definition '” + beanName + “’ since its singleton instance has been created too early. The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as ‘static’.”);
}
// 2.是全注解则将beandefinition放入map中
configBeanDefs.put(beanName, (AbstractBeanDefinition)beanDef);
}
}
if (!configBeanDefs.isEmpty() && !IN_NATIVE_IMAGE) {
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
Iterator var15 = configBeanDefs.entrySet().iterator();
// 3.然后遍历这个map
while(var15.hasNext()) {
Entry<String, AbstractBeanDefinition> entry = (Entry)var15.next();
AbstractBeanDefinition beanDef = (AbstractBeanDefinition)entry.getValue();
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
Class<?> configClass = beanDef.getBeanClass();
// 4.进行cglib代理,为@Configuration注解的类生成增强类
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (this.logger.isTraceEnabled()) {
this.logger.trace(String.format(“Replacing bean definition ‘%s’ existing class ‘%s’ with enhanced class ‘%s’”, entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
// 再通过beanDef.setBeanClass(enhancedClass)修改beanDefinition的BeanClass属性,
// 在bean实例化阶段,会利用反射技术将beanClass属性对应的类实例化出来
// 所以最终实例化出来的@Configuration bean是一个代理类的实例
beanDef.setBeanClass(enhancedClass);
}
}
enhanceConfigClasses.tag(“classCount”, () -> {
return String.valueOf(configBeanDefs.keySet().size());
}).end();
} else {
enhanceConfigClasses.end();
}
}
在ConfigurationClassUtils
类中声明了是Full @Configuration还是lite @Bean mode,可以看看源码:
【ConfigurationClassUtils
类中checkConfigurationClassCandidate
方法】
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// 如果存在@Configuration注解,则为BeanDefinition设置configurationClass属性为full
if (config != null && !Boolean.FALSE.equals(config.get(“proxyBeanMethods”))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, “full”);
} else {
if (config == null && !isConfigurationCandidate(metadata)) {
return false;
}
// 如果没有@Configuration注解或者有Component,ComponentScan,Import,ImportResource 注解中的任意一个,
// 或者存在 被@bean 注解的方法,则返回true.
// 则设置configurationClass属性为lite
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, “lite”);