applicationContext启动过程
首先去准备容器,也就是 new一个applicationcontext,Config.class为@ComponentScan注解标记的类。
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(Config.class);
调用它自己的构造方法。
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 1. 创建BeanFactory
// 2. 生成AnnotatedBeanDefinitionReader
// 3. 生成ClassPathBeanDefinitionScanner
this();
// 利用reader把componentClasses注册为一个BeanDefinition
register(componentClasses);
// 调用AbstractApplicationContext的refresh()方法,模板模式,会启动ApplicationContext
// 为什么叫refresh,而不叫start?
refresh();
}
看一下this()方法
因为AnnotationConfigApplicationContext对象继承了GenericApplicationContext对象,所以要先调用GenericApplicationContext的构造方法。
也就是创建了一个beanFactory对象。DefaultListableBeanFactory是beanFactory的最终实现类,功能及其强大。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
调用完父类的构造方法以后,回到自己的构造方法中。
public AnnotationConfigApplicationContext() {
// 在执行这个构造方法之前,会先执行父类的构造方法,会初始化一个beanFactory = new DefaultListableBeanFactory()
// 生成并注册5个BeanDefinition
// 1.ConfigurationClassPostProcessor
// 2.AutowiredAnnotationBeanPostProcessor
// 3.CommonAnnotationBeanPostProcessor
// 4.EventListenerMethodProcessor
// 5.DefaultEventListenerFactory
this.reader = new AnnotatedBeanDefinitionReader(this);
// 注册默认的includeFilter
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
这个方法主要是生成注册五个重要的BeanDefinition
1.ConfigurationClassPostProcessor 解析配置类(重点)BeanFactoryPostProcessor
2.AutowiredAnnotationBeanPostProcessor 用于@Autowired、@Value
3.CommonAnnotationBeanPostProcessor 用于@Resource
4.EventListenerMethodProcessor 用于@EventListener
5.DefaultEventListenerFactory 用于@EventListener
将这些重要的bean定义后,回到this.scanner = new ClassPathBeanDefinitionScanner(this);这个方法,添加@Component注解。这时已经将config.class的beanDefinition注册进去了。
然后接着到register(componentClasses);方法,通过reader将含有@Component注解的类转为beanDefinition。
然后调用refresh();方法先看一下源码,
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 刷新BeanFactory,得到一个空的BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备BeanFactory
// 1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
// 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
// 3. 记录ignoreDependencyInterface
// 4. 记录ResolvableDependency
// 5. 添加三个单例Bean
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 子类可以对BeanFactory进行进一步初始化
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
// 默认情况下:
// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
// 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化MessageSource,如果配置了一个名字叫做“messageSource”的BeanDefinition
// 就会把这个Bean创建出来,并赋值给ApplicationContext的messageSource属性
// 这样ApplicationContext就可以使用国际化的功能了
initMessageSource();
// Initialize event multicaster for this context.
// 设置ApplicationContext的applicationEventMulticaster
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 执行子类的onRefresh方法
onRefresh();
// Check for listener beans and register them.
// 注册Listener
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 完成beanFactory的初始化(实例化非懒加载的单例bean)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 发布事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
看这一步obtainFreshBeanFactory(),点进去发现有两个实现类,
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
1.GenericApplicationContext
2.AbstractRefreshableApplicationContext
如果是GenericApplicationContext这个类去实现发现提示不能再次刷新报错。
而AbstractRefreshableApplicationContext则可以再次进行刷新。
相对于的AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以它是不能再次刷新的。
AnnotationConfigWebApplicationContext继承的是AbstractRefreshableWebApplicationContext,所以它是可以再次刷新的。
然后查看AbstractRefreshableApplicationContext的刷新逻辑,将bean和beanFactory等销毁再创建。
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
如果手动添加了beanFactoryPostProcessor,那么需要刷新refresh一下,否则加载不进来。也算是体现了为什么要refresh了。
为什么手动添加就需要刷新一下了呢?
手写demo如下,创建ac时不能入参,否则就会直接调用refresh方法。这个ac容器还只支持刷新一次,所以只能这么写。
写法如下:
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
applicationContext.register(Config.class);
applicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
applicationContext.refresh();
首先创建一个无参的AnnotationConfigApplicationContext对象,执行无参构造器时不执行refresh()方法。然后我们需要手动添加进去配置类,但没有这个对象时是无法添加进去的,所以只能先得到这个对象后,去添加这个配置类,然后再执行refresh,这时才会将配置类注册进去。
让我们回到refresh方法,查看这个方法invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 这个beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法,也就是刚才那个demo方法手动注册的。
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// BeanDefinitionRegistryPostProcessor是一个特殊的BeanFactoryPostProcessor,需要先执行postProcessBeanDefinitionRegistry方法
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// 保存当前需要执行的实现了BeanDefinitionRegistryPostProcessor接口的后置处理器
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先,先执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 判断这个类是否还实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 这里调用了getBean,所以生成一个BeanDefinitionRegistryPostProcessor的bean对象
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 然后,先执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
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();
// 最后,最后其他普通的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
boolean reiterate = true;
// 在一个BeanDefinitionRegistryPostProcessor中可以注册另一个BeanDefinitionRegistryPostProcessor,所以需要递归找出所有的BeanDefinitionRegistryPostProcessor
// 一个没有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor如果在内部注册了一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,那么就是没有实现PriorityOrdered接口的先执行
while (reiterate) {
reiterate = false;
// 这里会再一次拿到实现了PriorityOrdered接口或Ordered接口的BeanDefinitionRegistryPostProcessor,所以需要processedBeans进行过滤
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
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();
}
// 执行完BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法后,
// 再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 执行手动添加的非BeanDefinitionRegistryPostProcessor类型的Bean工厂后置处理器的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 如果beanFactory没有可以注册BeanDefinition的功能,则没有BeanDefinitionRegistryPostProcessor,则执行Bean工厂后置处理器的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 在默认情况下,上面的步骤中只有一个BeanDefinitionRegistryPostProcessor会执行,就是ConfigurationClassPostProcessor,因为它是Spring默认在添加进去的
// BeanDefinitionRegistryPostProcessor是特殊的BeanFactoryPostProcessor,在上面的逻辑中都处理完了
// 所以接下来就是处理普通的BeanFactoryPostProcessor
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 默认情况下会拿到两个,一个就是ConfigurationClassPostProcessor,一个就是EventListenerMethodProcessor
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 保存直接实现了BeanFactoryPostProcessor接口和PriorityOrdered接口的后置处理器
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 保存直接实现了BeanFactoryPostProcessor接口和Ordered接口的后置处理器
List<String> orderedPostProcessorNames = new ArrayList<>();
// 保存直接实现了BeanFactoryPostProcessor接口的后置处理器,不包括那些实现了排序接口的类
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 把所有BeanFactoryPostProcessor进行分类
for (String ppName : postProcessorNames) {
// 拿到的BeanFactoryPostProcessor包括了BeanDefinitionRegistryPostProcessor,所以要跳过
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 先执行实现了PriorityOrdered接口的BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 再执行实现了Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 最后执行普通的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 到此,所有的BeanFactoryPostProcessor都执行完了
// 对于BeanFactoryPostProcessor我们可以这么理解:它是去完善BeanFactory的,比如向BeanFactory中去注册BeanDefinition
// 就好比:BeanFactory是一张白纸,每个BeanFactoryPostProcessor都去这张白纸上去画上一笔,这个白纸就丰满了
// 所以这段代码,虽然内容很多,但是在默认情况下,主要就是执行了ConfigurationClassPostProcessor
// 1. 先执行了ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,基本上就是去注册BeanDefinition
// 2. 然后执行了ConfigurationClassPostProcessor的postProcessBeanFactory方法
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
总结一下:
先判断ApplicationContext手动添加的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册)。
然后就是判断实现了实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册)。
接着实现了Ordered接口的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册)。
最后将所有的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册),将所有没执行过的执行一次。
(这么做的目的是分组执行beanDefinition的注册,按先后顺序。PriorityOrdered>Ordered>无)
执行完postProcessBeanDefinitionRegistry后,再执行全部的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法。
对于BeanFactoryPostProcessor接口我们可以这么理解:它是去完善BeanFactory的,比如向BeanFactory中去注册BeanDefinition
就好比:BeanFactory是一张白纸,每个BeanFactoryPostProcessor都去这张白纸上去画上一笔,这个白纸就丰满了
在默认情况下,主要就是执行了ConfigurationClassPostProcessor
1.先执行了ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,基本上就是去注册BeanDefinition
2. 然后执行了ConfigurationClassPostProcessor的postProcessBeanFactory方法。
ConfigurationClassPostProcessor
因为spring默认是执行ConfigurationClassPostProcessor这个bean,所以来详细分析一下里面的内容。
在调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry时,在processConfigBeanDefinitions方法里有这么一个方法
ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)
该方法的作用:检查BeanDefinition是不是配置类候选者,
那么什么样的BeanDefinition符合呢?
1. 存在@Configuration的就是配置类,或者
2. 存在@Component,@ComponentScan,@Import,@ImportResource,或者
3. 存在@Bean标注的方法
源码:
//存在@Configuration,并且proxyBeanMethods=true
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods")))
static {
//有这四个注解的话就作为候选者
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
//是否有@Bean
return metadata.hasAnnotatedMethods(Bean.class.getName());
识别了以后做什么? ----开始解析配置类
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry-》processConfigBeanDefinitions-》 parse-》processConfigurationClass-》doProcessConfigurationClass
具体解析都在doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 1. 如果配置bean上有@Component注解,递归去解析内部类上的注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass);
}
// Process any @PropertySource annotations
// 2. 解析@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");
}
}
// Process any @ComponentScan annotations
// 3. 解析@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) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 扫描得到BeanDefinition,解析@ComponentScan里的各种属性
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 检查扫描所得到BeanDefinition是不是配置Bean,基本上都有@Component注解,所以都是配置类
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 4. 解析@Import,getImports方法返回AppConfig.class上定义的Import注解中所导入的类的信息
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
// 5. 解析@ImportResource,得到导入进来的spring的xml配置文件,然后解析
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);
}
}
// Process individual @Bean methods
// 6. 解析配置类中的加了@Bean注解的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
// 7. 如果配置类实现了某个接口,那么则解析该接口中的加了@Bean注解的默认方法
processInterfaces(configClass, sourceClass);
// Process superclass, if any
// 8. 如果有父类,则返回父类给上层遍历进行处理
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
解析顺序:@Component-》@PropertySource-》@ComponentScan-》@Import-》@ImportResource-》@Bean
再回到这个方法processConfigBeanDefinitions。此时我们已经通过parse方法将配置类都解析出来了。
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 利用reader解析ConfigurationClass,同时注册BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
比如我断点到这里有这么几个ConfigurationClass:
现在我们进入到reader对象的loadBeanDefinitions方法
loadBeanDefinitions-》loadBeanDefinitionsForConfigurationClass-》loadBeanDefinitionsForBeanMethod
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName();
// Do we need to mark the bean as skipped by its condition?
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeanMethods.add(methodName);
return;
}
if (configClass.skippedBeanMethods.contains(methodName)) {
return;
}
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
Assert.state(bean != null, "No @Bean annotation attributes");
// 获取到@bean上的名字,第一个为beanName,后面的为别名,如:
//@Bean({"user","2","3"})
//public User user(){
//System.out.println("1");
//return new User();}
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
//取出第一个beanName
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
// 将剩余的添加到别名
for (String alias : names) {
this.registry.registerAlias(beanName, alias);
}
//判断重复@Bean
if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
"' clashes with bean name for containing configuration class; please make those names unique!");
}
return;
}
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setResource(configClass.getResource());
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
if (metadata.isStatic()) {
// static @Bean method
if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
}
else {
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
}
beanDef.setUniqueFactoryMethodName(methodName);
}
else {
// instance @Bean method
beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName);
}
if (metadata instanceof StandardMethodMetadata) {
beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
}
//设置Bean注入方式为构造器注入
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
Autowire autowire = bean.getEnum("autowire");
if (autowire.isAutowire()) {
beanDef.setAutowireMode(autowire.value());
}
boolean autowireCandidate = bean.getBoolean("autowireCandidate");
if (!autowireCandidate) {
beanDef.setAutowireCandidate(false);
}
//设置bean的初始化和销毁方法
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
//设置bean的作用域
ScopedProxyMode proxyMode = ScopedProxyMode.NO;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
if (attributes != null) {
beanDef.setScope(attributes.getString("value"));
proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = ScopedProxyMode.NO;
}
}
// Replace the original bean definition with the target one, if necessary
BeanDefinition beanDefToRegister = beanDef;
if (proxyMode != ScopedProxyMode.NO) {
BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
new BeanDefinitionHolder(beanDef, beanName), this.registry,
proxyMode == ScopedProxyMode.TARGET_CLASS);
beanDefToRegister = new ConfigurationClassBeanDefinition(
(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
}
if (logger.isTraceEnabled()) {
logger.trace(String.format("Registering bean definition for @Bean method %s.%s()",
configClass.getMetadata().getClassName(), beanName));
}
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
看一下@Bean判重的方法isOverriddenByExistingDefinition(beanMethod, beanName)里面这一块逻辑
//用于判断beanName是否重复,重复的话只有第一个被注册
if (existingBeanDef instanceof ConfigurationClassBeanDefinition) {
ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef;
if (ccbd.getMetadata().getClassName().equals(
beanMethod.getConfigurationClass().getMetadata().getClassName())) {
if (ccbd.getFactoryMethodMetadata().getMethodName().equals(ccbd.getFactoryMethodName())) {
ccbd.setNonUniqueFactoryMethodName(ccbd.getFactoryMethodMetadata().getMethodName());
}
return true;
}
else {
return false;
}
}
会先扫描@Component,再扫描@Bean
相对于@Component而言,@Bean中默认是允许被覆盖的,所以说最后@Bean生成的对象会保留下来。
被@Component注入的bd是ScannedGenericBeanDefinition,
被@Bean注入的db是ConfigurationClassBeanDefinition
如果两个都是@bean,beanName相同,则只会生成第一个。
一个小demo:
//同时一个@Component也有一个user对象,最终会生成的对象是第一个@Bean
@Bean
public User user(){
System.out.println("1");
return new User(); //最终会生成一个这一个user
}
@Bean("user")
public User user1(){
System.out.println("2");
return new User();
}
通过@Component得到的bean是通过autowire=no
通过@Bean得到的bean是通过构造方法的
关于@Configuration注解,生成代理对象的意义。
@ComponentScan("com.chuan")
@Configuration
public class Config {
@Bean
public User user(){
User user =new User();
System.out.println("1"+user);
return user;
}
@Bean
public UserService userService(){
User user =user();
System.out.println("2"+user);
return new UserService(user);
}
}
结果为:
1com.chuan.model.User@551bdc27
2com.chuan.model.User@551bdc27
原理:因为该配置类被@Configuration标注了以后,创建了user之后放在了单例池里,之后创建userService时会让代理对象去单例池寻找,不会重复创建对象了。
源码里又提到了FactoryBean,到底怎么转成FactoryBean,需要再了解了解。
--这个FactoryBean指的就是该配置类,FactoryMethod是@Bean这个方法
总结:
解析Config(注册的配置类)类,生成对应的ConfigurationClass再扫描,扫描到的类都会生成对应的BeanDefinition,并且同时这些类也是ConfigurationClass再解ConfigurationClass的其他信息,比如@ImportResource注解的处理,@Import注解的处理,@Bean注解的处理