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”);
}
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
跟踪到这里,基本上就比较明朗了,可以得到我们想要的答案
- 在
ConfigurationClassUtils
类中的checkConfigurationClassCandidate
标记是Full @Configuration还是lite @Bean mode
- 通过
"full".equals(configClassAttr)
判断是否是全类注解
- 是全注解则将beandefinition放入map中
configBeanDefs.put
- 遍历这个map
- 使用cglib技术为配置类生成一个enhancedClass
- 通过
enhancer.enhance
进行cglib代理,为@Configuration注解的类生成增强类
- 再通过
beanDef.setBeanClass(enhancedClass)
修改beanDefinition的BeanClass属性,在bean实例化阶段,会利用反射技术将beanClass属性对应的类实例化出来,所以最终实例化出来的@Configuration bean是一个代理类的实例
使用了@Configuration
注解的类,属于Full @Configuration
。@Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系,保证@Bean的对象作用域受到控制,避免多例。@Configuration
类中的@Bean
地方会被CGLIB进行代理。Spring会拦截该方法的执行,在默认单例情况下,容器中只有一个Bean,所以我们多次调用user()
方法,获取的都是同一个对象。
对于@Configuration注解的类中@Bean标记的方法,返回的都是一个bean,在增强的方法中,Spring会先去容器中查看一下是否有这个bean的实例了,如果有了的话,就返回已有对象,没有的话就创建一个,然后放到容器中。
是如何进行代理的,咱们还可以继续跟踪:点开enhancer.enhance
,进入ConfigurationClassEnhancer
类,在这个类中会去执行cglib代理类中的代理方法,如下:
【ConfigurationClassEnhancer
类中static
静态方法】
static {
CALLBACKS = new Callback[]{new ConfigurationClassEnhancer.BeanMethodInterceptor(),
new ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor(), NoOp.INSTANCE};
CALLBACK_FILTER = new ConfigurationClassEnhancer.ConditionalCallbackFilter(CALLBACKS);
logger = LogFactory.getLog(ConfigurationClassEnhancer.class);
objenesis = new SpringObjenesis();
}
cglib代理主要就是callBacks中的方法,点进去可以看到是一个接口,其中有一个实现类就是和cglib相关的
image-20210115201141656
四、总结
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
手绘了下图所示的kafka知识大纲流程图(xmind文件不能上传,导出图片展现),但都可提供源文件给每位爱学习的朋友
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
[外链图片转存中…(img-U70mhMct-1712091208826)]
[外链图片转存中…(img-mnUw2pD0-1712091208827)]
[外链图片转存中…(img-L33yoF33-1712091208827)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
手绘了下图所示的kafka知识大纲流程图(xmind文件不能上传,导出图片展现),但都可提供源文件给每位爱学习的朋友
[外链图片转存中…(img-atPdAflG-1712091208828)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!