@Configuration注解 -【Spring底层原理】

public User() {

System.out.println(“User对象”);

}

}

public class User2 {

public User2() {

System.out.println(“User2对象”);

}

}

这是一个最简单的spring项目,在配置类中有@Configuration注解,我们运行启动类,可以看到如下打印信息:

image-20210115101414931

image-20210115101414931

如果去掉配置类中的@Configuration注解会怎样呢,去掉之后,咱们来看看打印信息:

image-20210115101618212

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()),进入源码查看:

PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法】

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);,继续跟踪,进入源码查看:

PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法】

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

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”);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值