spring源码目录
git注释项目地址:https://github.com/chaitou/spring-framework-master.git
如果使用调试模式,跟进来下面代码倒不会有什么疑问,但是这一步代码的跳转确十分奇特,值得去探究一番。
在上一节讲到,首先spring在AbstractBeanFactory
类中创建了ObjectFactory
的对象,并重写了getObject()
方法,然后将他传给DefaultSingletonBeanRegistry
。此时DefaultSingletonBeanRegistry
调用了singletonFactory.getObject()
,getObject()
又调用了creatBean()
,因此实际调用的是AbstractBeanFactory
类的creatBean()
。而AbstractBeanFactory
类又被AbstractAutowireCapableBeanFactory
所继承,并且重写了其creatBean()
,因此最后调用的就是以下代码
// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 1. 锁定class,确保能根据class,className属性正确获取到对应class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
// 设置上一步获取到的Class
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 2. 校验和准备覆盖的方法(指:lookup-method, replace-method)
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
/**
* 3. 实例化前的后置处理器
* 给BeanPostProcessors一个机会返回代理替换调真实的实例,主要是来执行实现了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor
* AOP核心方法,具体内容到AOP再解答
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 4. 核心逻辑
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
lookup-method
、replace-method
方法 public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
// 循环检查override方法是否存在,有无重载
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
// 寻找替换的类方法的个数(可能出现重载)
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
// 找不到,报错
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
// 有且仅有1个,则说明没有重载,后续可以直接用。如果有重载后续还得进行解析,看看哪个重载方法最适合
else if (count == 1) {
// Mark override as not overloaded, to avoid the overhead of arg type checking.
mo.setOverloaded(false);
}
}
后置处理器
(墙裂推荐看一下后置处理器的使用:spring BeanPostProcessor 生命周期),目前还未开始实例化bean
,但是在下一段代码doCreateBean()
,将马上开始bean的实例化
,因此在这里调用实例化前的before后置处理器
是合适的。大家到这里只要知道一下后置处理器是怎么用的就行,一般来说这里都是返回null。(需要了解一下AOP的targetSource代理
就是在这里完成的,一旦被AOP接手,将通过cglib
会生成一个完全不同bean,并且是已经实例化、填充、初始化
过的,因此一旦bean不为空则需要应用初始化的after后置处理,然后直接返回代理bean,不再继续往下创建。) protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 确认bean在初始化阶段之前
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 确认当前beanName所要返回的最终类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 初始化前置处理,在这里
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 实例化后置处理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 实例化前置处理
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
上方代码频繁出现InstantiationAwareBeanPostProcessors
,该类是一个后置处理器接口。如下,总的有4个方法,1、2两个是用在实例化前后
,3、4则是用在属性填充步骤
的。也就是说只要有类实现了该接口,且重写了相关方法,则后续所有bean的创建都将被重写的方法所修改。所以后置处理器并不复杂,只是一个调用的过程,难的是有多少子类继承了它,这些子类又进行了哪些处理的操作?比如@Autowired
、AOP
等等,子类太多肯定无法每个都吃透,后续我们会单独挑出@Autowired详解
,看看@Autowired
是如何通过重写这些方法达到自动注入的目的spring源码16: @Autowired实现原理
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 是单例的情况下清空缓存
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/**
* 1. 实例化bean,这一阶段是调用构造器生产实例的阶段
*
* 如果有使用@Autowired构造器注入,则在该阶段完成属性的注入。
* (注意这里是Autowired构造器,而不是我们正常使用的注解在属性上)
* @Autowired
* public Outer(Inner inner) {
* this.inner = inner;
* }
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
/**
* 2. beanDefinition合并后的后置处理
* 比如@Autowired在属性上,就是在这里解析的,但是仅仅只是单纯的解析,还没有实现注入
*/
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 当mbd是单例,且允许循环引用,且正在被创建,则提前曝光该对象
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 3. 将该bean提前曝光,具体做法是创建一个ObjectFactory对象,再将对象加入到singletonFactories缓存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//
/**
* 4. 填充属性
* 如果@Autowired注解属性,则在上方完成解析后,在这里完成注入
*
* @Autowired
* private Inner inner;
*/
populateBean(beanName, mbd, instanceWrapper);
// 5. 初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 6. 被依赖检测
/**
* 假设 B, C, D均依赖A,当前正在创建A
* dependentBeanMap的key = A, value = B, C, D
* 要检测的是B, C, D是否正确注入了A,而不是要检测A,所以叫被依赖检测
*/
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// exposedObject跟bean一样,说明初始化操作没用应用Initialization后置处理器改变exposedObject
// 注意一下这里用的 == 号,说明是引用是否相等的判断
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
// 引用都不相等了,也就是现在的bean已经不是当时提前曝光的bean了
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// dependentBeans也就是B, C, D
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
// 循环 B, C, D
for (String dependentBean : dependentBeans) {
/**
* 如果B, C, D已经创建完了,那么他们拿到的肯定是A提前曝光的引用
*
* 但是这个判断又说明了现在的bean已经不是提前曝光的那个bean了,那这样B, C, D注入的A就是有问题的,抛出异常
* 这里有非的条件,里层也个非,需要留心这个逻辑
*/
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 7. 根据scope注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
instance(实例化)
,也就是调用构造函数,new出对应Class对象的过程。其中根据参数类型还分为有参构造函数跟无参构造函数,又根据是否有override
函数分为JDK代代理和cglib代理。后面做详解populateBean(属性填充)
,将所有属性填充到bean实例中initializeBean(初始化)
// 省略getter、setter
public class A {
@Autowired
private B b;
}
public class B {
@Autowired
private A a;
}
public class ABeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof A) {
A a = new A();
a.setB(((A) bean).getB());
bean = a;
}
return bean;
}
}
// XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="a" class="A"/>
<bean id="b" class="B"/>
<bean id="myBeanPostProcessor" class="ABeanPostProcessor"/>
<context:component-scan base-package="autowire"/>
</beans>
// 报错信息
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Bean with name 'a' has been injected into other beans [b] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
scope
注册bean,其中destroy-method
销毁方法也是在这里注册的完成创建并返回,接下去会详细介绍上面的步骤,包括循环依赖、实例化、属性填充、初始化
、以及@Autowired
的注入