看Spring源码要带有目的地学习,不然很容易被其复杂的继承体系绕的找不着北。因此这篇文章从大处着手,先是大体理出整个Spring启动的脉络,来分析Spring 的Ioc和DI是如何实现的,然后再从细节分析Spring Ioc一些常见的问题。对于阅读源码来说,最重要的是学习其中的设计思路、编程思想,但是最初级地学习是要先弄清它的实现。对于博主来说水平有限,只能谈谈自己的理解。(为了简化理解,本文省略了一些源码,关注核心部分)
一、整体来看Spring的启动过程。
1. refresh->开始刷新容器
我们从容器初始化入口类的refresh方法开始,这个方法由父类AbstractApplicationContext 定义实现,使用SpringBoot方式启动也会进入到该方法初始化Spring容器以及Bean。这个方法里调用obtainFreshBeanFactory和finishBeanFactoryInitialization这两个关键方法。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
........
try {
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
.........
}
}
2. obtainFreshBeanFactory->准备容器,解析Bean
这个方法调用子类的refreshBeanFactory。主要是创建出Bean的容器,也就是BeanFactory,本质上就是一个Map,存放BeanDefinition,然后就使用xml或者注解的方式解析出BeanDefinition,然后将这些Bean注册到容器中,到这一步对于Bean的前置工作就做好了。返回BeanFactory后下一步当然就是对于容器的Bean进行初始化了。这里的refreshBeanFactory还是基于模板方法,在父类定义出该方法,具体怎么刷新容器交由子类AbstractRefreshableApplicationContext
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
//当前已经有Bean容器,就先将其Bean销毁,然后关闭容器
destroyBeans();
closeBeanFactory();
}
try {
//创建容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//加载Bean 定义
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
3. loadBeanDefinitions->Bean载入容器
具体就是解析出BeanDefinition,由于层次太深,这里先不往下走。
4. finishBeanFactoryInitialization->非懒加载单例Bean的初始化
refresh方法中更关键的方法就是finishBeanFactoryInitialization,在这个方法中调用beanFactory.preInstantiateSingletons()进行非懒加载单例Bean的初始化,而多例则是在getBean的时候创建,这里的初始化交由DefaultListableBeanFactory子类进行
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
.......
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
5. preInstantiateSingletons
这个方法中真正调用了getBean方法,稍后会认真分析这里,是怎么对Bean进行初始化的。相关的调用链getBean->doGetBean->createBean->doCreateBean
@Override
public void preInstantiateSingletons() throws BeansException {
......
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
.........
getBean(beanName);
}
}
// Trigger post-initialization callback for all applicable beans...
}
6. doCreateBean->实例化、属性注入、初始化
终于走到了doCreateBean,可以开始对具体的Bean进行初始化了。这里的核心方法就是createBeanInstance(反射获取对象的实例)、populateBean属性注入、initializeBean初始化。下面还是要细致地分析这个方法
二、分析Spring的一些细节
1. loadBeanDefinitions如何将Bean载入容器
loadBeanDefinitions可以由不太子类来实现,一种方式是载入xml文件,然后解析dom树来解析获取BeanDefinition,由于目前主流是使用注解来定义Bean的,所以这篇文章还是基于注解加载BeanDefinition。
- 从loadBeanDefinitions进入到register,register方法遍历class文件,registerBean注册Bean
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
...........
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
try {
Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader());
if (logger.isTraceEnabled()) {
logger.trace("Registering [" + configLocation + "]");
}
reader.register(clazz);
}
}
}
}
- doRegisterBean解析beanClass文件,生成基于注解的Bean,最后调用registerBeanDefinition注册Bean。到这一步终于完成Bean容器的初始化了。
<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析注解,设置Bean的lazy、primary等属性
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
......
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
- registerBeanDefinition将Bean注入到map容器,这里有一些细节可以关注一下
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
......
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
//这里省略了如果已存在bean,是否允许覆盖的判断,以及一些debug日志
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//如果Bean已经开始创建了,
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
//其实博主不是很理解这里为什么要这样new出新的 updatedDefinitions ,然后再赋值。。。
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
2. 初始化Bean
- 首先是对所有非懒加载并且单例的Bean初始化,然后对于实现了SmartInitializingSingleton的类进行回调。
@Override
public void preInstantiateSingletons() throws BeansException {
........
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历所有bean,对于单例非懒加载的Bean初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
//如果是实现了FactoryBean,有一些特殊处理
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
//省略了对于实现了SmartInitializingSingleton方法的回调。如果想要在Bean初始化之后执行一些操作,可以实现这个接口SmartInitializingSingleton。
}
- getBean()->doGetBean,在doGetBean里面代码就很长了,先尝试从缓存中取Bean对象,(这里面还用了三层缓存解决循环依赖问题,那为什么要使用三层,两层或者一层不可以吗?)如果缓存中获取不到,那么就要判断是单例还是多例还是其他,具体看注释。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//获取唯一的beanName
final String beanName = transformedBeanName(name);
Object bean;
// 尝试从缓存中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//····省略了log
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// // 如果当前容器中没有指定的 bean,且当前容器的父容器不为空
// 则从父容器中去找,如果父容器也没有,则沿着当前容器的继承体系一直向上查找
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 获取当前 bean 所依赖bean 的 beanName,下面的 getBean(dependsOnBean) 方法会触发
// getBean() 的递归调用,直到取到一个不依赖任何其它 bean 的 bean 为止。
// 比如:beanA 依赖了 beanB,而 beanB 依赖了 beanC,那么在实例化 beanA 时会先实例化
// beanC,然后实例化 beanB 并将 beanC 注入进去,最后实例化 beanA 时将 beanB 注入
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 创建单例,这里使用了匿名表达式
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//多例Bean的创建
else if (mbd.isPrototype()) {
// 原型模式 (Prototype) 每次都会创建一个新的对象
Object prototypeInstance = null;
try {
// Spring的扩展点,回调方法
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//回调方法
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 要创建的 bean 既不是单例模式,也不是原型模式,则根据该 bean元素 在配置文件中
// 配置的生命周期范围,选择实例化 bean 的合适方法,这种在 Web 应用程序中
// 比较常用,如:request、session、application 等的生命周期
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 省略了对Bean的校验工作。。
return (T) bean;
}
- createBean->doCreateBean开始实例化Bean了。这里的代码十分长,但是我们只要抓住核心,就不会找不到重点。。。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 如果这个 bean 是单例的,则从缓存中获取这个 beanName 对应的 BeanWrapper实例,并清除
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//!!!!重点关注的地方,实例化对象!!!!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 省略了Spring的一些调用点。。
//earlySingletonExposure 表示单例允许循环依赖,beanName正在创建。
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");
}
// 这里是一个 ObjectFactory 的匿名内部类,为了防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//!!!!这里也是重点,依赖注入就是在这里完成的
populateBean(beanName, mbd, instanceWrapper);
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);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 如果根据名称获取的已注册的 bean 和正在实例化的 bean 是同一个
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
// 如果当前 bean 依赖其他 bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
- 继续往下看createBeanInstance创建实例对象,使用策略模式实例化getInstantiationStrategy().instantiate
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//.....其他的特殊处理
// 没有特殊处理的话,就默认使用无参构造器进行初始化
return instantiateBean(beanName, mbd);
}
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
//从源码中我们可以看到其调用了 SimpleInstantiationStrategy 实现类来生成 bean
//对象,这个类是 Spring 用来生成 bean 对象 的默认类,它提供了两种策略来实例化
//bean 对象,一种是利用 Java 的反射机制,另一种是直接使用 CGLIB。
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
- 如果 配置的bean 中没有方法覆盖,则使用 Java 的反射机制实例化对象,否则使用 CGLIB
public class SimpleInstantiationStrategy implements InstantiationStrategy {
// 使用初始化策略实例化 bean对象
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
// 如果 配置的bean 中没有方法覆盖,则使用 Java 的反射机制实例化对象,否则使用 CGLIB
if (beanDefinition.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (beanDefinition.constructorArgumentLock) {
// 获取对象的构造方法对 bean 进行实例化
constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
// 如果前面没有获取到构造方法,则通过反射获取
if (constructorToUse == null) {
// 使用 JDK 的反射机制,判断要实例化的 bean 是否是接口
final Class clazz = beanDefinition.getBeanClass();
// 如果 clazz 是一个接口,直接抛出异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
// 这里使用了一个 PrivilegedExceptionAction 的匿名内部类,使用反射机制获取 bean 的构造方法
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
public Constructor run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 根据传入的 Constructor,在 BeanUtils 中调用该 Constructor 的
// newInstance(Object...) 方法,实例化指定对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
/**
* !!!!!!!!!!!!!!
* 使用 CGLIB 来实例化对象
* 调用了 CglibSubclassingInstantiationStrategy 中的实现
* !!!!!!!!!!!!!!
*/
return instantiateWithMethodInjection(beanDefinition, beanName, owner);
}
}
}
- 使用CGLIB实例化的过程
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
/**
* 下面两个方法都通过实例化自己的私有静态内部类 CglibSubclassCreator,
* 然后调用该内部类对象的实例化方法 instantiate() 完成实例化
*/
protected Object instantiateWithMethodInjection(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
return new CglibSubclassCreator(beanDefinition, owner).instantiate(null, null);
}
@Override
protected Object instantiateWithMethodInjection(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Constructor ctor, Object[] args) {
return new CglibSubclassCreator(beanDefinition, owner).instantiate(ctor, args);
}
/**
* 为避免 3.2 之前的 Spring 版本中的外部 cglib 依赖而创建的内部类。
*/
private static class CglibSubclassCreator {
private static final Log logger = LogFactory.getLog(CglibSubclassCreator.class);
private final RootBeanDefinition beanDefinition;
private final BeanFactory owner;
public CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
this.beanDefinition = beanDefinition;
this.owner = owner;
}
// 使用 CGLIB 进行 bean对象 实例化
public Object instantiate(Constructor ctor, Object[] args) {
// 实例化 Enhancer对象,并为 Enhancer对象 设置父类,生成 Java 对象的参数,比如:基类、回调方法等
Enhancer enhancer = new Enhancer();
// 将 bean 本身作为其父类
enhancer.setSuperclass(this.beanDefinition.getBeanClass());
enhancer.setCallbackFilter(new CallbackFilterImpl());
enhancer.setCallbacks(new Callback[] {
NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(),
new ReplaceOverrideMethodInterceptor()
});
// 使用 CGLIB 的 create() 方法生成实例对象
return (ctor == null) ? enhancer.create() : enhancer.create(ctor.getParameterTypes(), args);
}
}
}
- 实例化完之后,就该进行属性注入了,属性注入的方式包括@Autowird,@Resource等
/**
* 为属性赋值,完成依赖注入
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 获取 RootBeanDefinition 中设置的 属性值PropertyValues,这些属性值来自对
// bean元素 的解析
PropertyValues pvs = mbd.getPropertyValues();
// 省略检查BeanWrapper和在设置属性之前调用 bean 的 PostProcessor 后置处理器
// 依赖注入开始,首先处理 autowire 自动装配的注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 对 autowire 自动装配的处理,根据 bean 名称自动装配注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据 bean 类型自动装配注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 省略检查容器是否持有用于处理单例模式 bean 关闭时的后置处理器
/**
* !!!!!!!!!!!
* 对属性进行依赖注入
* !!!!!!!!!!!
*/
applyPropertyValues(beanName, mbd, bw, pvs);
}
本文Bean初始化部分未完待更,目前先写到属性注入这里吧。。
三、一些常见问题
1. 讲讲Spring,Bean生命周期,bean创建过程
Spring启动过程简要来说就是创建容器,解析Bean封装成BeanDefinition,将Bedefinition注册到容器中,然后遍历容器,对容器中非单例懒加载的Bean初始化,初始化过程先是初始化依赖的Bean,然后递归进行初始化,每次先尝试从三级缓存中取Bean,然后再初始化,保证了Bean的唯一性。对于Bean的生命周期来说,主要包含实例化、属性注入、初始化、销毁四个生命周期。
2. 循环依赖如何解决,为什么三层依赖,两层可以吗?
Spring能够解决的是setter注入方式,不能解决构造器注入的循环依赖。使用的是Java的引用传递和三级缓存解决的,第一级缓存是Bean实例的缓存singletonObjects,第二层是提前暴露出来的缓存earlySingletonObjects,第三层是Bean工厂的缓存singletonFactory。取缓存的逻辑如下所示:Spring首先从singletonObjects(一级缓存)中尝试获取,如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获取,如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过singletonFactory.getObject()(三级缓存)获取。如果获取到了则移除对应的singletonFactory,将singletonObject放入到earlySingletonObjects,其实就是将三级缓存提升到二级缓存中!
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
那么工厂缓存是什么时候设置的呢?我们通过查看createBean的源码可以发现是在实例化之后。这段代码发生在createBeanInstance之后,也就是说单例对象此时已经被创建出来的。这个对象已经被生产出来了,虽然还不完美(还没有进行初始化的第二步和第三步),但是已经能被人认出来了(根据对象引用能定位到堆中的对象),所以Spring此时将这个对象提前曝光出来让大家认识,让大家使用
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
.....
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
//设置三级缓存
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
那么为什么不用二级缓存呢?为了解决代理对象的循环依赖才使用三级缓存
https://www.cnblogs.com/semi-sub/p/13548479.html
3. Spring注入方式
构造方法注入,setter注入,基于注解的注入
网友评论