环境:spring-context....:5.2.15 spring-boot: 2.3.11
基于此环境,我们只需要关心 AnnotationConfigApplicationContext 和AnnotationConfigServletWebServerApplicationContext ,他们互为父子关系。我们主要关心子容器(web容器)
前言:
本篇重点:
- Spring 如何扫描并加载beanDefinition
- Spring bean的实例化过程
- Spring 如何解决循环依赖
- Spring 给我们创建bean的过程中留下了哪些扩展方法(或者说bean的生命周期)
1.refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
设置启动时间 标记状态 占位符处理
this.prepareRefresh();
如果是AbstractRefreshableApplicationContext的子类如ClassPathXmlApplicationContext 这里会从资源文件中加载BeanDefinition 注册bean定义
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
1.1 注册几个Bean BeanPostProcessor 比如 ApplicationContextAwareProcessor
this.prepareBeanFactory(beanFactory);
try {
源码注释:Allows post-processing of the bean factory in context subclasses. 子类可以在这步的时候添加一些特殊的 BeanPostProcessor 或者做其他的事
this.postProcessBeanFactory(beanFactory);
按照PriorityOrdered,Ordered 普通类型顺序注册BeanDefinitionRegistryPostProcessor(ConfigurationClassPostProcessor最主要的beanDefinition注册器) ,调用postProcessBeanDefinitionRegistry方法注册beanDefinition
1.2 ConfigurationClassPostProcessor 在此处开始获取工程主类 根据注解信息扫描注册beanDefinition
按照PriorityOrdered,Ordered 普通类型顺序注册BeanFactoryPostProcessor 调用postProcessBeanFactory方法
this.invokeBeanFactoryPostProcessors(beanFactory);
同理按照PriorityOrdered,Ordered 普通类型顺序注册 BeanPostProcessor
this.registerBeanPostProcessors(beanFactory);
国际化
this.initMessageSource();
注册 ApplicationEventMulticaster 事件广播器 SimpleApplicationEventMulticaster
this.initApplicationEventMulticaster();
web容器如tomcat 初始化
this.onRefresh();
注册事件监听器
this.registerListeners();
1.3 内部调用DefaultListableBeanFactory#preInstantiateSingletons 实例化所有非lazy-init的bean 大部分的bean在此实例化
this.finishBeanFactoryInitialization(beanFactory);
顺序调用Lifecycle实例 广播事件 ContextRefreshedEvent
this.finishRefresh();
} catch (BeansException var9) {
...
} finally {
this.resetCommonCaches();
}
}
}
1.1 prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
...
//处理接口 ApplicationContextAware 注入依赖
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//如果依赖下面几个接口的实现类 忽略他们 有对应的BeanPostProcessor会处理
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//如果bean依赖了下面几个类型 会注入方法中指定的bean
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//该处理器 负责注册事件监听器 :bean实现了ApplicationListner 会在初始化时注册到applicationListeners中 ,销毁时移除
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
...
}
BeanPostProcessor: bean初始化 前后进行作用,可辅助注入依赖(ApplicationContextAwareProcessor),增强处理(AnnotationAwareAspectJAutoProxyCreator)等。
BeanFactoryPostProcessor:类似BeanPostProcessor,但是作用阶段是加载BeanDefinition阶段,实例化bean之前
1.2 ConfigurationClassPostProcessor#processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
...
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
判断bean定义上是否有@Configuration注解 同时根据proxyBeanMethods true/false 标注是full/lite 模式 (full模式该类会代理增强 内部的@Bean 方法允许互相调用而不产生新的实例)
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
...candidateNames order 排序....
...是否有自定义beanName 生产器...
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//开始扫描 一般candidates只会有一个 就是我们的工程主类
1.2.1
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());
}
将扫描出来的信息 注册为beanDefinition : 被@Import的(META-INF中扫描到的都算import),
@Bean标注的方法(将方法所在类的名称设置为beanDefinition的factoryMethodName,声明此对象由工厂方法创建)
调用扫描到的 ImportBeanDefinitionRegistrar.registerBeanDefinitions方法
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
...
}
1.2.1 ConfigurationClassParser#parse
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
...
if (bd instanceof AnnotatedBeanDefinition) {
1.2.2.1 内部调用 processConfigurationClass
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
...
}
//调用 DeferredImportSelector -> AutoConfigurationImportSelector在这里扫描classpath下 META-INF/spring.factories中所有的EnableAutoConfiguration
this.deferredImportSelectorHandler.process();
}
1.2.1.1 ConfigurationClassParser#processConfigurationClass
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
//根据@Conditional判断是否需要跳过
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
...
// Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
//每个被扫描出来的bean定义基本都会执行进入这个方法 判断是否需要对其内部类 注解信息进行解析,最终其class属性会放入到下方 configurationClasses中 ,防止重复扫描注册
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
1.2.1.1.1 ConfigurationClassParser#doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
//内部类 是不是 有Component,ComponentScan,Import,ImportResource 或者 有带@Bean注解的方法 如果有, 获取该类重新调用上方processConfigurationClass 循环扫描
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
// @ComponentScan 作用处
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
ComponentScan value中标明的包路径,如果未标明获取其类所在包路径
for (AnnotationAttributes componentScan : componentScans) {
//将带Component 的类扫描出来 同时注册beanDefinition
1.2.1.1.1.1
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//判断是否有@Configuration注解 或者 有Component,ComponentScan,Import,ImportResource 或者 有带@Bean注解的方法 如果有 同上 扫描该类
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// @import处理 被import 的类如果属于 ImportSelector,ImportBeanDefinitionRegistrar 会被实例化 ,其他类型的当做Configuration处理
//ImportSelector 调用selectImports 获取 类名数组 触发额外的 BeanDefinition注册
//ImportBeanDefinitionRegistrar实例化 后被注册到 Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> 中 后续统一调用
// Process any @ImportResource annotations
// 遍历所有@Bean方法 添加到 该configClass的 Set<BeanMethod> beanMethods中
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
.. 处理默认方法 父类...
return null;
}
1.2.1.1.1.1 ComponentScanAnnotationParser#parse
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
注意这个对象 ClassPathBeanDefinitionScanner 父类 ClassPathBeanDefinitionScanner,我们可直接使用或者继承ClassPathScanningCandidateComponentProvider复写isCandidateComponent方法,来达到过滤候选类的作用,如果你需要自定义框架的话。mybatis feign注册client都是这么做的
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
...
根据@ComponentScan 添加过滤器 需要扫描的类 需要排除的类
ClassPathBeanDefinitionScanner 在构造方法中根据环境判断指定了需要扫描@Component @Named @ManagedBean
...
获取扫描的包路径
...开始扫描 感兴趣的可以继续看看 scanCandidateComponents 方法
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
太长不看:ConfigurationClassPostProcessor处理BeanDefinition逻辑:
ConfigurationClassPostProcessor作为BeanDefinitionRegistryPostProcessor ,在invokeBeanFactoryPostProcessors阶段,被调用执行postProcessBeanDefinitionRegistry方法
从当前容器中获取现有beanDefinition,判断是否包含Configuration注解,如果包含加入candidates集合中,当前阶段,一般只有启动类上会有
根据candidates集合,调用ConfigurationClassParser.parse方法,
parse方法分两步
第一步:根据集合中的每一个元素,调用doProcessConfigurationClass方法
1.doProcessConfigurationClass,判断当前处理的类是否有@Component并且其内部类是否有 @Component,@ComponentScan,@Import,@ImportResource注解 或者 有带@Bean注解的方法,如果内部类符合条件,判断之前是否执行过,进而
选中该内部类调用doProcessConfigurationClass方法,达到嵌套扫描的效果
2.获取当前处理的类@ComponentScan注解,如果有,根据basePackages或当前类所在包路径,扫描带@Component注解的类,并注册成BeanDefinition,遍历当前扫描出来并注册的BeanDefinition,判断是否@Component,@ComponentScan,@Import,@ImportResource注解 或者 有带@Bean注解的方法 ,调用doProcessConfigurationClass方法
3.import处理,如果当前处理的类带有@Import注解,遍历其value值
如果是ImportSelector实现类,原地实例化,并调用selectImports方法获取classNames[]数组,同时继续就classNams[]数组中的类进行Import处理
如果是ImportBeanDefinitionRegistrar实现类,原地实例化,此时不调用 registerBeanDefinitions方法,而是将实例收集起来,后续统一调用
非上述两类,将该类收集起来后续统一处理,然后调用doProcessConfigurationClass方法
4.处理@Bean方法 收集起来,统一处理
第二步:
调用DeferredImportSelector ,AutoConfigurationImportSelector在这里扫描META-INF/spring.factories中的EnableAutoConfiguration类,作为Import处理
parse方法结束后,处理收集到的Import类,@Bean方法 注册BeanDefinition,调用ImportBeanDefinitionRegistrar的registerBeanDefinitions方法 注册BeanDefinition
1.3 DefaultListableBeanFactory#preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//是不是FactoryBean类型
if (isFactoryBean(beanName)) {
1.3.1 内部调用AbstractBeanFactory#doGetBean方法 这里获取的是工厂对象
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
...
如果是SmartFactoryBean并且isEagerInit为true ,马上调动getObject方法创建目标对象,否则只有目标对象被依赖了才会触发调用(注意:FactoryBean创建的bean没有populate阶段 不会进行属性注入,只有initializeBean.postProcessAfterInitialization ,但FactoryBean本身具备所有普通bean都有的阶段)
}
}
else {
创建实例 (createBeanInstance,populate,in)
getBean(beanName);
}
}
}
for (String beanName : beanNames) {
如果bean是SmartInitializingSingleton调用其afterSingletonsInstantiated方法
}
}
1.3.1 AbstractBeanFactory#doGetBean
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
如果name是$开始 代表现在获取的是FactoryBean类型 这里获取真正的beanName
String beanName = transformedBeanName(name);
Object bean;
尝试从缓存中获取bean
1.3.1.1 内部调用 DefaultSingletonBeanRegistry#getSingleton(beanName, true)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
如果在这里拿到了目标对象,同时传参name,beanName,目的同上,因为需要将FactoryBean和其产出的对象分开来,如果name是$开始,直接返回 如果不是,调用其getObject方法返回目标对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
...
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
@DependsOn 如果依赖其他bean,先创建依赖项 :这里的依赖不是属性依赖 而是A必须先于B创建,是创建先后顺序的关系
}
}
我们这里只关心单例的创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
1.3.1.2 内部调用 AbstractAutowireCapableBeanFactory#doCreateBean 真正创建bean的入口
return createBean(beanName, mbd, args);
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
...
return (T) bean;
}
1.3.1.1 DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
//Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); ObjectFactory是一个ObjectFactory 是一个@FunctionalInterface
//Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
allowEarlyReference 为true时允许从第三级缓存中获取资源
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
三级缓存一旦存在 就调用getObject方法存入二级缓存
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
1.3.1.2 AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();存放的是beanName 和 FactoryBean的关系
这里尝试直接从缓存中获取 如果获取到了,代表此beanName对应的是一个FactoryBean,何时放入缓存?:在本
阶段preInstantiateSingletons前,registerBeanPostProcessors实例化相关BeanPostProcessor注入其需要的依赖时,Spring按类型查找相关的bean,遍历查找发现当前查找对象时是FactoryBean时,继续调用getObjectType方法判断是不是需要的类型。此时,就会将FactoryBean缓存起来,防止类型注入时重复进行遍历判断
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
非FactoryBean创建
1.3.1.2.1 创建bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
预处理 @Value @Resoure @Inject @Autowired @PostContruct @PreDestroy...
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
1.3.1.2.2 落入三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
1.3.1.2.3 属性注入
populateBean(beanName, mbd, instanceWrapper);
1.3.1.2.4 初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
1.2.1.2.5 解决循环依赖问题
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
...
}
}
....
return exposedObject;
}
创建FactoryBean过程:
- DefaultListableBeanFactory#getBeanNamesForType() -->
- DefaultListableBeanFactory#doGetBeanNamesForType() -->
- AbstractBeanFactory#isTypeMatch() -->
- AbstractAutowireCapableBeanFactory#getTypeForFactoryBean() -->
- AbstractAutowireCapableBeanFactory#getSingletonFactoryBeanForTypeCheck()
1.3.1.2.1 AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...
if (instanceSupplier != null) {
//如果beanDefinition中声明了Supplier,则调用Supplier.get方法创建实例。
//其好处在于更灵活的创建bean,一般框架上才用到。
//我们可以使用ImportBeanDefinitionRegistrar注册definition,
//注册的同时声明其Supplier,这样会比FactoryBean相对更优雅 灵活
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
//前文说到 @Bean 声明的对象 beanDefinition会标明 factoryMethodName,所有的@Bean 创建进入这个分支
//内部调用 1.2.1.2.1.1 ConstructorResolver#instantiateUsingFactoryMethod
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
...调用 SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors 筛选出合适的构造器,这里是AutowiredAnnotationBeanPostProcessor 在处理,处理逻辑:如果有多个构造 取有@Autowired 或 @Inject的 (同时存在多个会报错)构造器,如果都没有 那就不处理 结束
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
...反射获取无参给构造 创建对象 到这一步如果没有无参构造就会抛异常了...
return instantiateBean(beanName, mbd);
}
1.3.1.2.1.1 ConstructorResolver#instantiateUsingFactoryMethod
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
..
@Bean声明 所在的类 我们默认为configuration类
String factoryBeanName = mbd.getFactoryBeanName();
....
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
//调用一次后会缓存目标方法及参数 非单例模式才会进入到里面
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
}
}
如果beanDefinition中 isFactoryMethodUnique 为true实例化方法无歧义(有歧义时是当前类存在多个同名方法),则直接获取beanDefinition中的factoryMethodToIntrospect(同判断是否为FactoryBean,在前文按类型注入bean时获取方法返回值判断是否为需要的bean,此时会将对factoryMethodToIntrospect进行赋值), 否则获取当前实例中所有的方法,查找同名方法。后续进行权重判断合适的方法
...查找合适的调用方法...
if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidates.get(0);
//如果方法唯一 且不需要参数 直接反射调用方法创建实例
if (uniqueCandidate.getParameterCount() == 0) {
...
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
if (candidates.size() > 1) {
public 参数个数多的 优先选择
candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
}
....
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Method candidate : candidates) {
else {
...
这里最终调用 DefaultListableBeanFactory#doResolveDependency 根据类型查找依赖(标明了@Quliafier 、@Primary的Bean会优先进行匹配 如果匹配到多个 会尝试按名称进行匹配)
一般进入到这里beanDefinition 中的autowireMode 默认为3 AUTOWIRE_CONSTRUCTOR,常用的@Component声明为0 AUTOWIRE_NO ,AUTOWIRE_BY_NAME,AUTOWIRE_BY_TYPE 一般用在FactoryBean创建对象,比如mybatis,feign创建client
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
...
}
...
获得最终的方法 反射调用 创建bean实例
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
1.3.1.2.2 AbstractAutowireCapableBeanFactory#getEarlyBeanReference
在创建bean阶段完成后 这里将这样一个方法保存到三级缓存 singletonFactories中,目的是为了当发生依赖关系后,可以获取到被SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference 作业之后的bean
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
这里最重要的一个处理器就是 AnnotationAwareAspectJAutoProxyCreator:创建代理对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
1.3.1.2.3 AbstractAutowireCapableBeanFactory#populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//bean创建完毕后的 进行属性注入前 会作用的一个阶段
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//AUTOWIRE_BY_NAME AUTOWIRE_BY_TYPE 都不需要显示的声明@Autowired, Spring会遍历属性 去除简单属性和 beanDefinition中 propertyValues中不存在key的属性, 通过名称/类型查找注入bean,一般除非显示的声明,我们的bean 都是 AUTOWIRE_NO 或 AUTOWIRE_CONSTRUCTOR
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
...
循环调用InstantiationAwareBeanPostProcessor.postProcessProperties 进行依赖处理
这里最重要的两个处理器:CommonAnnotationBeanPostProcessor处理@Resource @AutowiredAnnotationBeanPostProcessor处理@Autowired @Value @Inject
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
...
pvs = pvsToUse;
}
}
}
....
if (pvs != null) {
//遍历 允许参数转换 如符合规范的String转换为List(基于ConversionService) 调用set方法进行注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
1.3.1.2.4 AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
InitDestroyAnnotationBeanPostProcessor处理@PostConstruct ApplicationContextAwareProcessor处理aware依赖
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
afterPropertiesSet方法调用 @Bean(声明的initMethod)方法调用
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
..
}
if (mbd == null || !mbd.isSynthetic()) {
最重要的 AbstractAutoProxyCreator(AnnotationAwareAspectJAutoProxyCreator)在这里完成代理化,当然,有可能提前,因为这个处理器属于SmartInstantiationAwareBeanPostProcessor,如果产生循环依赖,会调用getEarlyBeanReference 提前创建代理对象
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
到这里我们先简单过下一个标记@Component的普通bean创建过程
即根据相关beanDefinition,根据无参构造创建bean,处理依赖关系,进行依赖注入,调用初始化方法,进行代理化,返回代理对象
1.3.1.2.5 解决循环依赖最后一步
我们先回头看#### 1.3.1.1 这里的代码
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
三级缓存一旦存在 就调用getObject方法存入二级缓存 并从三级缓存中移除
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
if (earlySingletonExposure) {
传参false 表示至多只从二级缓存中获取 1级缓存是最终的对象 2级缓存可以理解为临时存储代理对象(这里存放的bean还未完成属性注入) 3级缓存为普通对象->代理对象的function
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
...
}
}
所谓循环依赖,就是A->B B->A ,Spring实例化A时,调用构造/工厂方法创建A,将A->代理A的function存入三级缓存,接着进行属性注入,发现需要注入实例B,接着调用getBean(B), 创建B,将B->代理B的function存入三级缓存,给B注入依赖时,发现依赖A,调用getBean(A),发现三级缓存中存在A,调用function完成A的代理化,方法结束,将代理A放入二级缓存,注入代理A,实例B属性注入阶段结束,接着进行初始化,代理化,将代理B存入一级缓存,实例化B结束。回到A的属性注入阶段,getBean(B)返回代理B,注入代理B,实例A的属性注入结束,A继续走初始化,代理化流程,在代理化的过程中,spring的处理逻辑是之前处理过了就不处理了,这时就会进走到上面的代码块 exposedObject = earlySingletonReference 从二级缓存中获取代理对象,完成普通bean->代理bean的替换,存入一级缓存,实例化A结束
注意: 属性注入是对原始对象的注入,代理对象是持有的原始对象的引用,所以直接用exposedObject = earlySingletonReference 是可以的,属性注入并不会丢失(代理对象只是在原有的对象基础上加了Advisor集合和InvocationHandler处理程序)
为什么要用三级缓存来存放各个阶段的bean呢,二级缓存可以满足要求吗?
首先,二级缓存可以不存放在这里,但是一定需要一个地方存放创建过的代理对象。假设我们移除了二级缓存,在多个bean互相依赖的场景:A依赖B,C。而B,C都依赖A,那么实例化A的过程将调用三级缓存function两次,为了不重复进行代理化只能再维护一个缓存,假设AnnotationAwareAspectJAutoProxyCreator内部多维护一个缓存,重复代理化过程中直接返回缓存中的对象。这样貌似能解决问题,但是AnnotationAwareAspectJAutoProxyCreator只是BeanPostProcessor#postProcessAfterInitialization中的一环,每一环都需要加一个缓存防止重复执行,无论是从理解角度还是后期扩展角度,三级缓存function执行完毕直接放入二级缓存,不再调用 都是更优的解决方案。
最后我们用文字描述下创建bean的过程:
太长不看: Spring ioc 处理过程
容器初始化时,扫描class文件注册beanDefinition, 调用doGetBean创建bean
1.校验是否有dependsOn的依赖,如果有,优先实例化依赖项
2.将beanName存入 singletonsCurrentlyInCreation set中,只有为true才继续执行,否则抛出循环创建异常
在doCreateBean方法中完成bean的创建、依赖注入,初始化三个阶段
3.创建bean factoryBeanInstanceCache.remove / createBeanInstance:
factoryBeanInstanceCache.remove: 尝试从factoryBeanInstanceCache map中获取实例,这个map 是调用FactoryBean.getObject 后存放的对象,也就是由FactoryBean创建的对象,mybatis的dao对象就存放在这里
createBeanInstance:如果bean由@Bean方式创建,先实例化@Bean方法所在类,然后调用@Bean所在方法进行创建;
否则调用 SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors 确定合适的构造器创建bean
4.将SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference方法 存入三级缓存,方便循环依赖时提前完成代理化返回代理对象
5.依赖注入populateBean :这里会基于@Resource /@Autowired 调用不同的 InstantiationAwareBeanPostProcessor.postProcessProperties进行依赖处理,或者直接 基于 autowireMode 按名称/类型注入依赖
6.初始化initializeBean:调用BeanPostProcessor.postProcessBeforeInitialization方法进行处理,aware类型依赖在这里处理,以及@PostConstruct方法在这里调用,接着调用 afterPropertiesSet方法,如果有自定义的初始化方法如@Bean(initMethod = "xxx")也会被调用。最后调用 BeanPostProcessor.postProcessAfterInitialization,spring在这里根据Advisor判断是否需要进行代理化,并完成代理过程,返回代理对象
7.检查二级缓存中根据beanName查找,如果有对象存在且与当前实例相等,使用二级缓存中的对象进行返回。因为在循环依赖场景下会提前完成代理化
9.将实例存入一级缓存singletonObjects中,从二、三级缓存中移除,实例化bean结束
10.在所有非延迟初始化的bean创建完成后,遍历,如果有bean实现了SmartInitializingSingleton,调用其afterSingletonsInstantiated方法。
如何获取bean的构造/factoryMethod方法,及获取对应的依赖,见后续文章spring依赖处理
下面附带图片版,spring留下了大量的接口,使我们可以干预bean的生命周期,我们可以实现接口或使用相关注解
附 BeanDefinition* *
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
void setParentName(@Nullable String var1);
//bean定义也是可以继承的
@Nullable
String getParentName();
//设置类属性,可以通过反射创建bean实例
void setBeanClassName(@Nullable String var1);
@Nullable
String getBeanClassName();
void setScope(@Nullable String var1);
//设置是单例 原型、、、、
@Nullable
String getScope();
//设置是否懒加载
void setLazyInit(boolean var1);
boolean isLazyInit();
//一般两个bean之间没有显式的依赖关系,但是创建B需要先创建A
void setDependsOn(@Nullable String... var1);
String[] getDependsOn();
void setPrimary(boolean var1);
boolean isPrimary();
// @Bean注解所在类
void setFactoryBeanName(@Nullable String var1);
String getFactoryBeanName();
//@Bean注解所在方法
void setFactoryMethodName(@Nullable String var1);
String getFactoryMethodName();
//构造器参数
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !this.getConstructorArgumentValues().isEmpty();
}
//populate bean阶段 可用来赋值初始变量
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !this.getPropertyValues().isEmpty();
}
//生命周期回调用到
void setInitMethodName(@Nullable String var1);
String getInitMethodName();
void setDestroyMethodName(@Nullable String var1);
String getDestroyMethodName();
......
}