1.@Configuration注解作用
@Configuration用于定义配置类,可替换xml配置文件
,
被注解的类内部包含有一个或多个被@Bean注解的方法,
这些方法将会被AnnotationConfigApplicationContext
或AnnotationConfigWebApplicationContext
类进行扫描,
并用于构建bean定义,初始化Spring容器。
注意:@Configuration注解的配置类有如下要求:
@Configuration不可以是final类型;
@Configuration不可以是匿名类;
嵌套的configuration必须是静态类。
2. @Configuration注解使用
@Configuration
@ComponentScan(basePackages = "com.chr.test.configuration")
public class AppConfig {
@Bean(name="userDao")
public UserDao userDao(){
System.out.println("注入UserDao");
return new UserDao();
}
@Bean(name="orderDao")
public OrderDao orderDao(){
userDao();
return new OrderDao();
}
}
/**
* @author chenhairong3
* @description
* @date 2020/12/16
*/
public class OrderDao {
public OrderDao(){
System.out.println("OrderDao 无参构造函数被调用。");
}
public void insert() {
System.out.println("OrderDao.insert()被调用。");
}
}
/**
* @author chenhairong3
* @description
* @date 2020/12/16
*/
public class UserDao {
public UserDao(){
System.out.println("UserDao 无参构造函数被调用。");
}
public void insert() {
System.out.println("UserDao.insert()被调用。");
}
}
测试类:
/**
* @author chenhairong3
* @description
* @date 2020/12/16
*/
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext configApplicationContext = new
AnnotationConfigApplicationContext(AppConfig.class);
AppConfig appConfig = configApplicationContext.getBean(AppConfig.class);
OrderDao orderDao = (OrderDao) configApplicationContext.getBean("orderDao");
orderDao.insert();
UserDao userDao = (UserDao) configApplicationContext.getBean("userDao");
userDao.insert();
}
}
输出:
注入UserDao
UserDao 无参构造函数被调用。
OrderDao 无参构造函数被调用。
OrderDao.insert()被调用。
UserDao.insert()被调用。
3.思考
直接上验证结果:
/**
* @author chenhairong3
* @description
* @date 2020/12/16
*/
//@Configuration
@ComponentScan(basePackages = "com.chr.test.configuration")
public class AppConfig {
@Bean(name="userDao")
public UserDao userDao(){
System.out.println("注入UserDao");
return new UserDao();
}
@Bean(name="orderDao")
public OrderDao orderDao(){
userDao();
return new OrderDao();
}
}
输出:
注入UserDao
UserDao 无参构造函数被调用。
注入UserDao
UserDao 无参构造函数被调用。
OrderDao 无参构造函数被调用。
OrderDao.insert()被调用。
UserDao.insert()被调用。
从结果可以看出来,注释掉@Configuration注解,bean依然会被注入,但是userDao被注入了2次。
我们发现:
有@Configuration注解的时候,得到的appConfig对象是被cglib代理增加后的代理类对象
没有@Configuration注解的时候,得到的就是个普通的对象:
为什么会这样呢?就让我们带着疑问开始源码分析,解开@Configuration的神秘面纱。
4. 源码分析
从表面来看,当我们不加@Configuration注解的时候,我们的UserDao会被实例化两次,这违背了我们spring默认单例的设计原则,当加上我们的@Configuration注解的时候,UserDao只被实例化了一次。那么其底层到底做了什么,让我们来深追一下spring源码吧。
先看下整个debug跟踪调用的代码链路。然后再一步步讲解每一步代码。
从上面debug的链路可以看到整体的调用链路是:
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
从这个代码开始进入AnnotationConfigApplicationContext的构造函数:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
构造函数中this方法里面会注入ConfigurationClassPostProcessor这个BeanFactoryPostProcessor扩展类。
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
ConfigurationClassPostProcessor 实现了BeanDefinitionRegistryPostProcessor 这个接口。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
实现了这个接口的类,在容器bean实例化之前会调用 ConfigurationClassPostProcessor的如下2个方法
1.postProcessBeanDefinitionRegistry()
postProcessBeanFactory()
postProcessBeanDefinitionRegistry此方法会解析配置类(此例中的配置类AppConfig)中的元注解,比如@Configuration和@ComponetScan,然后解析元注解,如果注解是@Configuration注解,则设置属性:
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
非@Configuration注解,设置属性为:
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "lite");
postProcessBeanFactory()方法中会判断如果属性值为full,则会基于cglib给配置类生成cglib代理类,在代理类中设置拦截器类
new ConfigurationClassEnhancer.BeanMethodInterceptor()。
在BeanMethodInterceptor的Interceptor方法中实现对方法的拦截。
Interceptor方法中重要的逻辑:
if (this.isCurrentlyInvokedFactoryMethod(beanMethod)) {
if (ConfigurationClassEnhancer.logger.isWarnEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
ConfigurationClassEnhancer.logger.warn(String.format("@Bean method %s.%s is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
}
//如果当前线程的方法和beanMethod方法相同时候,说明是第一次创建对象,则调用目标对象的方法来创建对象
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
} else {
//如果当前线程的方法和beanMethod方法不相同时候,说明不是第一次创建对象,则直接从beanFactory中直接获取对象,保证单例。
return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
具体详细代码分析如下:
我们先从AnnotationConfigApplicationContext入口类开始分析:
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
进入对应的构造函数:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
进入this方法:
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
进入this.reader = new AnnotatedBeanDefinitionReader(this);
然后进入
AnnotationConfigUtils.registerAnnotationConfigProcessors()方法:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(4);
RootBeanDefinition def;
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
//在这里注入了ConfigurationClassPostProcessor这个类型的BeanDefinition
def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor")) {
def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor"));
}
if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) {
def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor"));
}
if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) {
def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader()));
} catch (ClassNotFoundException var6) {
throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) {
def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) {
def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory"));
}
return beanDefs;
}
def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); 上面最重要的代码,在这里注入了ConfigurationClassPostProcessor类型的BeanDefinition.用于解析@Configuration注解。
题外话:
上面还注入了另外几个比较重要的 PostProcessor。分别是
AutowiredAnnotationBeanPostProcessor(用于解析@Autowired的注解等)
RequiredAnnotationBeanPostProcessor(用于解析required的注解等)
CommonAnnotationBeanPostProcessor(用于解析@PostConstruct 和 @PreDestroy等注解 )
接下来开始进入ConfigurationClassPostProcessor源码进行分析:
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
上面已经说过ConfigurationClassPostProcessor继承自BeanDefinitionRegistryPostProcessor,而BeanDefinitionRegistryPostProcessor又继承自BeanFactoryPostProcessor。
BeanDefinitionRegistryPostProcessor执行的时候会顺序调用如下2个方法。
1.postProcessBeanDefinitionRegistry()
postProcessBeanFactory()
那么BeanFactoryPostProcessor什么时候被调用的呢?
在容器刷新方法refresh中如下图中标红的部分就是BeanFactoryPostProcessor被调用的地方:
在
接下来进入PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法:
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
if (beanFactory instanceof BeanDefinitionRegistry) {
//这里beanFactory是DefaultListableBeanFactory,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口。所以会进入if分支
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
//初始的时候beanFactoryPostProcessors是空的,所以不会进入下面的while循环
Iterator var6 = beanFactoryPostProcessors.iterator();
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();
//获取BeanDefinitionRegistryPostProcessor这种类型的postProcessorNames ,正好ConfigurationClassPostProcessor满足,然后会被找到
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var18 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//这个方法里面最终会调postProcessor.postProcessBeanDefinitionRegistry(registry);,ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry这个方法此时会被调用
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var18 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[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);
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var21 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var28 = 0; var28 < var10; ++var28) {
String ppName = var21[var28];
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);
currentRegistryProcessors.clear();
}
//这里会调用BeanFacotyPostProcessor的postProcessor.postProcessBeanFactory(beanFactory);即postProcessBeanFactory(beanFactory)方法被调用的地方
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var22 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var22; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var23 = orderedPostProcessorNames.iterator();
while(var23.hasNext()) {
String postProcessorName = (String)var23.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var26 = currentRegistryProcessors.iterator();
while(var26.hasNext()) {
ppName = (String)var26.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
从上面可以可以,会顺序调用ConfigurationClassPostProcessor的如下2个方法:
1.postProcessBeanDefinitionRegistry() 此方法用于解析Configuration注解,如果
配置类上有@Configuration注解,则设置属性 beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
否则则设置属性:
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "lite");
2.postProcessBeanFactory()
此方法会判断上面的属性值是否为“full”,如果是则生成配置类的增加类,并设置方法拦截,在拦截器方法内,实现单例的控制。
postProcessBeanDefinitionRegistry方法源码:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
} else if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
} else {
this.registriesPostProcessed.add(registryId);
//在这里进行解析
this.processConfigBeanDefinitions(registry);
}
}
//在这里进行解析
this.processConfigBeanDefinitions(registry);
进入此方法:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList();
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
if (!configCandidates.isEmpty()) {
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry)registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
HashSet alreadyParsed = new HashSet(configCandidates.size());
do {
//在这里进行解析
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());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet();
Iterator var12 = alreadyParsed.iterator();
while(var12.hasNext()) {
ConfigurationClass configurationClass = (ConfigurationClass)var12.next();
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
String[] var23 = newCandidateNames;
int var24 = newCandidateNames.length;
for(int var14 = 0; var14 < var24; ++var14) {
String candidateName = var23[var14];
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());
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();
}
}
}
进入
ConfigurationClassParser的parse方法:
最终会调到如下方法:
进入
doProcessConfigurationClass方法:
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className != null && beanDef.getFactoryMethodName() == null) {
Object metadata;
if (beanDef instanceof AnnotatedBeanDefinition && className.equals(((AnnotatedBeanDefinition)beanDef).getMetadata().getClassName())) {
metadata = ((AnnotatedBeanDefinition)beanDef).getMetadata();
} else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)beanDef).hasBeanClass()) {
Class<?> beanClass = ((AbstractBeanDefinition)beanDef).getBeanClass();
metadata = new StandardAnnotationMetadata(beanClass, true);
} else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
} catch (IOException var5) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " + className, var5);
}
return false;
}
}
if (isFullConfigurationCandidate((AnnotationMetadata)metadata)) {
//在这里放入属性值
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
} else {
if (!isLiteConfigurationCandidate((AnnotationMetadata)metadata)) {
return false;
}
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "lite");
}
Integer order = getOrder((AnnotationMetadata)metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
} else {
return false;
}
}
isFullConfigurationCandidate方法源码:
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
return metadata.isAnnotated(Configuration.class.getName());
}
可以看到会判断如果有Configuration注解,则设置属性:beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
至此postProcessBeanDefinitionRegistry方法源码分析结束。主要逻辑就是获取配置类上的元注解,找到是否有@Configuration注解,有的话则设置beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
接下来重点分析postProcessBeanFactory方法:
进入enhanceConfigurationClasses方法,在这里会生成代理类,实现方法增强:
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap();
String[] var3 = beanFactory.getBeanDefinitionNames();
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {
String beanName = var3[var5];
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
//在这里会判断属性,如果属性值为full
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.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
this.logger.warn("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'.");
}
//如果属性值为full 则把beanDefinition加入configBeanDefs map中
configBeanDefs.put(beanName, (AbstractBeanDefinition)beanDef);
}
}
if (!configBeanDefs.isEmpty()) {
//因为上面加入过值,所以这里configBeanDefs肯定不会为空
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
Iterator var11 = configBeanDefs.entrySet().iterator();
while(var11.hasNext()) {
Entry<String, AbstractBeanDefinition> entry = (Entry)var11.next();
AbstractBeanDefinition beanDef = (AbstractBeanDefinition)entry.getValue();
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
try {
Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
if (configClass != null) {
//使用cglib动态代理生成代理类
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
beanDef.setBeanClass(enhancedClass);
}
}
} catch (Throwable var9) {
throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), var9);
}
}
}
}
进入
从源码可以看出,通过cglib动态代理生成了当前配置的的子类(enhancer.setSuperclass(configSuperClass);),然后设置了回调拦截器,
CALLBACKS = new Callback[]{new ConfigurationClassEnhancer.BeanMethodInterceptor(), new ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor(), NoOp.INSTANCE};
然后进入new ConfigurationClassEnhancer.BeanMethodInterceptor()中的intercept方法
@Nullable
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs, MethodProxy cglibMethodProxy) throws Throwable {
ConfigurableBeanFactory beanFactory = this.getBeanFactory(enhancedConfigInstance);
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
Scope scope = (Scope)AnnotatedElementUtils.findMergedAnnotation(beanMethod, Scope.class);
if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
beanName = scopedBeanName;
}
}
if (this.factoryContainsBean(beanFactory, "&" + beanName) && this.factoryContainsBean(beanFactory, beanName)) {
Object factoryBean = beanFactory.getBean("&" + beanName);
if (!(factoryBean instanceof ScopedProxyFactoryBean)) {
return this.enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
}
}
if (this.isCurrentlyInvokedFactoryMethod(beanMethod)) {
//在这里判断如果当前线程调用的方法和目标方法一样,则表示是第一次创建,则调用代理类的父类(即目标类)方法,注入实例
if (ConfigurationClassEnhancer.logger.isWarnEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
ConfigurationClassEnhancer.logger.warn(String.format("@Bean method %s.%s is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
}
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
} else {
// 在这里判断如果当前线程调用的方法和目标方法不一样,则表示以前创建过,则直接从beanFactory工厂通过beanName 获取实例
return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
}
实现单例控制的重点代码:
if (this.isCurrentlyInvokedFactoryMethod(beanMethod)) {
//在这里判断如果当前线程调用的方法和目标方法一样,则表示是第一次创建,则调用代理类的父类(即目标类)方法,注入实例
if (ConfigurationClassEnhancer.logger.isWarnEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
ConfigurationClassEnhancer.logger.warn(String.format("@Bean method %s.%s is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
}
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
} else {
// 在这里判断如果当前线程调用的方法和目标方法不一样,则表示以前创建过,则直接从beanFactory工厂通过beanName 获取实例
return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
比如测试代码中:
@Bean(name="orderDao")
public OrderDao orderDao(){
userDao();
return new OrderDao();
}
this.isCurrentlyInvokedFactoryMethod(beanMethod)这个方法中,执行到 userDao()这个代码的时候,beanMethod即userDao,而当前线程调用到的方法确实orderDao,方法不同,所以会走到return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);从beanFactory中获取bean实例,而不是重新创建,从而实现单例控制。
可以看debug示例:
接下来看resolveBeanference()方法:
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs, ConfigurableBeanFactory beanFactory, String beanName) {
boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
Object var20;
try {
if (alreadyInCreation) {
beanFactory.setCurrentlyInCreation(beanName, false);
}
boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
if (useArgs && beanFactory.isSingleton(beanName)) {
Object[] var7 = beanMethodArgs;
int var8 = beanMethodArgs.length;
for(int var9 = 0; var9 < var8; ++var9) {
Object arg = var7[var9];
if (arg == null) {
useArgs = false;
break;
}
}
}
//重点,从beanFactory中获取bean实例
Object beanInstance = useArgs ? beanFactory.getBean(beanName, beanMethodArgs) : beanFactory.getBean(beanName);
if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
if (!beanInstance.equals((Object)null)) {
String msg = String.format("@Bean method %s.%s called as bean reference for type [%s] but overridden by non-compatible bean instance of type [%s].", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(), beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
try {
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
msg = msg + " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
} catch (NoSuchBeanDefinitionException var14) {
}
throw new IllegalStateException(msg);
}
if (ConfigurationClassEnhancer.logger.isDebugEnabled()) {
ConfigurationClassEnhancer.logger.debug(String.format("@Bean method %s.%s called as bean reference for type [%s] returned null bean; resolving to null value.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(), beanMethod.getReturnType().getName()));
}
beanInstance = null;
}
Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
if (currentlyInvoked != null) {
String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
beanFactory.registerDependentBean(beanName, outerBeanName);
}
var20 = beanInstance;
} finally {
if (alreadyInCreation) {
beanFactory.setCurrentlyInCreation(beanName, true);
}
}
return var20;
}
至此源码分析到此结束。
流程总结:
在refresh方法之前注入ConfigurationClassPostProcessor这个BeanFacotryPostProcessor,然后再refresh方法
this.invokeBeanFactoryPostProcessors(beanFactory);中,ConfigurationClassPostProcessor被调用,然后依次执行类中的如下2个方法:
postProcessBeanDefinitionRegistry() 此方法完成对配置类的注解进行解析,如果有@Configuration注解,则设置属性为:beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
postProcessBeanFactory()方法。在这个方法会判断上面的属性是有为full,如果是,则给配置类生成cglib代理类,给代理类上设置MethodInterceptor拦截器,在interceptor()方法对目标方法增强。
如果拦截方法和当前线程调用方法一样,则调用目标类的方法生成bean实例,否则从beanFactory根据beanName获取bean实例,实现单例的控制。