加载可持续性Bean
熟练Spring使用方法的开发者都知道,在我们需要对象时,Spring会自动呈上对象,那么这些Bean对象也分很多种,对于单例Bean或者是lazy-init=”false”,Spring希望他们在容器建立时就存在于容器中,所以在refresh()方法中,初始化结束之前,有这么一段代码:
@Override
public void refresh() throws BeansException, IllegalStateException {
...
finishBeanFactoryInitialization(beanFactory);
...
}
前面已经隐隐约约的说了下这个方法将要干些什么,不多说,我们直接进入方法:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 配置类型转换服务
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 如果BeanFactory没有后置处理,那么添加一个内嵌的StringValueResolver
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// 先加载LoadTimeWeaverAware类型的Bean
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用暂时的类加载器,暂时类加载器主要用于类型匹配,默认为空,当有load-time织入时,则需要指定暂时类加载器
beanFactory.setTempClassLoader(null);
// 暂时冻结已经注册的BeanDefinition
beanFactory.freezeConfiguration();
// 关键点:实例化可持续Bean
beanFactory.preInstantiateSingletons();
}
我们直接看关键点DefaultListableBeanFacotry#preInstantiateSingletons()方法:
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 复制一份BeanDefinitionNames
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历筛选符合要求的Bean
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是否是FactoryBean类型的Bean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
// 是否渴望被夹在,默认false
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
// 不是FactoryBean类型的Bean,直接getBean()
getBean(beanName);
}
}
}
// Bean的实例化后处理
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
Bean加载的核心就是getBean操作,比如说我们写测试代码的时候,通常都会这么写:
ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
System.out.println(ac.getBean("beanName"));
所以我们集中分析一下getBean()方法,getBean()方法是BeanFactory的方法,我们都知道Spring采用了工厂模式,根据笔者之前的关于工厂模式的文章,我们会发现getBean()方法实际上是用于生产Bean:
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
熟悉了Spring的代码之后,你会发现,一般doGetBean()才是真正的业务实现,getBean()有多种形式,基本的有直接根据BeanName获取Bean,还有根据Class或参数获取Bean,但是它们都会调用一个统一的方法doGetBean():
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 转换对应的BeanName
final String beanName = transformedBeanName(name);
Object bean;
// 从单例池中获取对象,变相解决了单例模式循环依赖的问题
// 如果单例中存在循环依赖的问题时,Spring在创建Bean时不等Bean创建就将Bean的ObjectFactory提早曝光
Object sharedInstance = getSingleton(beanName);
// 获取Bean实例对象
if (sharedInstance != null && args == null) {
...
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果在原型模式下,出现了循环调用的问题,那么抱歉,只能抛出异常了
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果当前BeanFactory中不包含这个BeanName,那么直接请教老父亲
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 寻亲名字
String nameToLookup = originalBeanName(name);
if (args != null) {
// 去老父亲的BeanFactory中寻找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// 去老父亲的BeanFactory中寻找(与if中的调用参数不同)
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 如果不仅是为了做类型检查,那么登记一下
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 当时我们分析组装BeanDefinition的时候,发现使用的GenericBeanDefinition
// Spring在这里将GernericBeanDefinition转换为RootBeanDefinition
// 如果指定的BeanName还有老父亲,那么会囊括对应的父类信息
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 安检
checkMergedBeanDefinition(mbd, beanName, args);
// 循环依赖递归
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);
getBean(dep);
}
}
// 创建Bean实例
// 创建单例模式的Bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 创建Bean
return createBean(beanName, mbd, args);
}
...
}
});
// 获取Bean实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型模式创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 既不是单例,也不是原型的,请走这边
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
...
}
// 身份检查
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
...
}
// 完活
return (T) bean;
}
即使是去掉了一部分逻辑,这部分代码看起来依然复杂,为了让大家看的更舒心,不浪费进来的时间,我先归纳下doGetBean()的大体逻辑:
- 转换BeanName。在主歌部分,我们在注册BeanDefinition的时候,有BeanName注册和Alias注册,这里就是对这个传参进行转换,找到对应的Bean。
- 首先看看单例缓存池中是否有对应的Bean。有就实例化,没有接着找。
- 单例缓存池中没有,不代表这个Bean不是单例,可能是还没加载。接下来先进性原型模式检查。原型价差通过后,如果当前BeanDefinition池中没有,并且有老父亲,那么去老父亲哪里看一看。
- 如果上述逻辑都没找到,那么只能动手创建了。首先获取对应BeanDefinition,然后就是根据BeanDefinition创建对应的Bean实例。
- 返回创建的Bean,完活。
归纳起来感觉很容易,接下来我们就一步一步的分析。
转换BeanName
其实,这段代码意思很明了,但是笔者很好奇,所以想带大家来看一下AbstractBeanFactory#transformedBeanName():
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
不墨迹,接着走BeanFactoryUtils.transformedBeanName():
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
String beanName = name;
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
return beanName;
}
FactoryBean一般和普通Bean形式不一样,他们会带一个&符号,这里把它去掉了,我们接着看AbstractBeanFactory#canonicalName()方法:
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
如果有alias,用alias存的BeanName,如果没有,直接返回当前名称。
BeanName转换,笔者就带领大家看完了,其实笔者就是想让大家看看,是优先使用Alias还是BeanName。
从单例池中获取Bean
接下来就到了从单例池中获取Bean,AbstractBeanFactory#getSingleton():
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
中转一下后,设置允许早期依赖后,继续往下走,我们继续看AbstractBeanFactory#getSingleton():
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
具体步骤如下:
- 首选,从缓存中获取单例。
- 如果缓存中没有,并且这个Bean正在创建过程中,那么先全局锁住缓存,从早期缓存中获取对象。
- 如果早期缓存中没有,并且允许早期依赖,那么从对象工厂中获取对象。
- 返回对象。
简单的来说就是依次从singletonObjects、earlySingletonObject以及singletonFacotories中获取,然后返回对象(可能为空)。
然后我们依次介绍下这几个Map:
- singletonObjects。存储BeanName和实例对象的映射关系。
- earlySingletonObjects。也是存储BeanName和实力对象之间的映射关系,不同于singletonObjects的是,如果Bean正处于创建过程中,就能从earlySingletonObjects中获取到。
- objectFactories。存储BeanName和工厂的映射关系,ObjectFacotory可直接生产Bean实例对象。
回到getBean()主方法中,如果从缓存中获取到了对应的单例,那么我们就会对其进行实例化,实例化调用的是AbstractBeanFactory#getObjectForBeanInstance(),这是个高频率调用方法,几乎所有Bean实例化都需要调用这个 方法,我们来看下具体的实现:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// 如果名字是工厂类型的Bean,但是身体不是,抛出异常
// 我可能生产了一个假的Bean
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// 如果想要直接获取工厂实例,给它
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
// 尝试从缓存中获取实例对象
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
// 这个时候已经进本可以确定,Bean是FactoryBean的类型
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 获取对应的BeanDefinition
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 关键点:获取实例对象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
总结一下:
- 对FactoryBean进行校验。
- 对非FactoryBean不做任何处理。
- 尝试从缓存中获取实例对象。
- 通过getObjectFromFactoryBean()方法获取实例对象。
获取实例对象
我们先来看看如何从缓存中获取实例对象的,ApplicationBeanFactory#getCachedObjectForFactoryBean():
protected Object getCachedObjectForFactoryBean(String beanName) {
Object object = this.factoryBeanObjectCache.get(beanName);
return (object != NULL_OBJECT ? object : null);
}
就是从factoryBeanObjectCache中获取对应的beanName,这个factoryBeanObjectCache是一个ConcurrentHashMap,里面存放的是BeanName→Object的单例对象缓存。
接下来我们看一下获取实例对象的关键点,AbstractBeanFacotry#getObjectFromFactoryBean()方法:
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 如果是Bean是单例的,并且singletonObjects中包含这个BeanName
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 还是从缓存中获取
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 关键点:缓存中没有获取到的话就生产一个
object = doGetObjectFromFactoryBean(factory, beanName);
// 因为锁住的是singletonObjects,生产完看一下缓存池中是否已经存在了,因为单例只需生产一次
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 如果存在,指针变换
if (alreadyThere != null) {
object = alreadyThere;
}
// 不存在处理一下
else {
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
...
}
// 并把这个Bean放入到缓存中
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
// 如果不是单例Bean,那么就直接生产吧
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
// 处理实例对象
object = postProcessObjectFromFactoryBean(object, beanName);
}
...
}
return object;
}
}
总结一下:
- 首先判断需要生产的实例对象是单例的还是其他类型的。
- 如果是单例的,首先要锁住singletonObjects缓存,然后根据不同的情况获取实例对象,这个过程中要保证单例Bean只实例化一次。
- 如果不是单例的,那么就直接生产实例对象。
AbstractBeanFacotry#getObjectFromFactoryBean()主要是围绕不同情况如何创建对象,接下来我们就看看AbstractBeanFacotry#doGetObjectFromFactoryBean()**是如何创建对象的:
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
// 安全检查
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
...
}
else {
object = factory.getObject();
}
}
...
// 这里的实例对象不允许null,捕捉到null就会抛出异常
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
抽茧剥丝到最后,其实就是问了这句话:object = factory.getObject(),通过FactoryBean生产出对象。
获取实例对象后,还需要做一些后置处理,我们看看AbstractAutowireCapableBeanFacotry#postProcessObjectFromFactoryBean()都做了些什么处理:
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
继续跟下去,AbstractAutowireCapableBeanFacotry#applyBeanPostProcessorsAfterInitialization():
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
后置处理其实就是获取Bean的后置处理器,然后依依对其进行实现,后置处理器绝大部分都需要开发者进行开发,然后注册到后置处理器集合中(ArrayList存储),
代码看到这里,从缓存中获取单例的实现就已经结束了,我们回到最初的起点,接着看下一道风景线。
创建Bean
如果单例缓存中不存在,那么我们就需要创建Bean了,创建Bean主要分三种情形:单例Bean,原型Bean和其他类型Bean。
创建单例Bean
我们首先复习一下AbstractBeanFactory#doGetBean()方法中,创建单例Bean的方法:
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
...
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
如果是单例模式,还是会调用getSingleton()获取实例对象,不过和之前的形式不同。
再看getSingleton()之前,我们需要看一下这个匿名内部类,这里面new了一个ObjectFactory,其中创建了一个Bean。我们首先对这个AbstractAutowireCapableBeanFactory#createBean()方法入手:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 如果有方法覆盖
try {
mbdToUse.prepareMethodOverrides();
}
...
try {
// 如果有后置处理,那么允许返回一个代理而不是一个Bean的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 短路
if (bean != null) {
return bean;
}
}
...
try {
// 创建Bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
...
}
继续往下走,AbstractAutowireCapableBeanFactory#doCreateBean():
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 首先看下实例缓存中有没有Bean,如果有,移除。
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果没有,创建一个新实例
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 锁住后置处理
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 进行各种类型的后置处理,aop就是在这里织入的
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
...
mbd.postProcessed = true;
}
}
// 看看是否需要放入到ObjectFactory缓存中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 放入ObjectFactory缓存中
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Bean实例化
Object exposedObject = bean;
try {
// 属性注入
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
...
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
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);
}
}
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.");
}
}
}
}
//
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
...
return exposedObject;
}
依然很复杂,没事,我们有时间。
总结一下,在进行分步解析:
- 首先看实例缓存中是否存在当前Bean,如果有,移除。
- 如果没有,创建对应的Bean实例。
- 后置处理。
- 看看有没有资格放入到缓存中。
- Bean实例化与属性注入
- 注册Bean。
创建Bean
由于第一步过于简单,我们直接进入第二步AbstractAutowireCapableBeanFactory#createBeanInstance():
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 获取BeanClass类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
// 用BeanWrapper包裹一层
BeanWrapper bw = new BeanWrapperImpl(instanceSupplier.get());
initBeanWrapper(bw);
return bw;
}
if (mbd.getFactoryMethodName() != null) {
// 直接通过工厂方法实例化
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
// 锁定构造函数的参数
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已经解析过,则不需要再次锁定
if (resolved) {
if (autowireNecessary) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认构造方法注入
return instantiateBean(beanName, mbd);
}
}
// 确认构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 根据构造方法参数的不同自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 直接实例化Bean
return instantiateBean(beanName, mbd);
}
我们还是分步骤解释一下:
- 获取BeanClass类型。其实主要是想检查一下Bean的Class是不是存在的,是不是public的,是不是有公共构造方法这些。
- 看看BeanDefinition中是否有实例提供,如果有实例提供,那么直接使用该实例即可。
- 如果这个BeanDefinition含有工厂方法,那么直接使用工厂方法进行实例化。
- 一个类可能有多个构造方法,根据参数固定到对应的构造方法。
- 如果已经解析过了,则使用解析好的构造方法,不需要再次锁定,根据是否自动注入来进行实例化。
- 如果参数不为空,则需要找到对应的构造方法,使用自动注入方式进行实例化。
- 如果以上情况全部落空,那么使用直接实例化Bean。
我们着重看两个实现吧,一次全部看完并不现实。
构造方法自动注入
首先我们看下AbstractAutowireCapableBeanFactory#autowireConstrutor()方法:
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
即将是一段毁天灭地,让你想立即关闭网页的代码,但是想装逼,请坚持看完ConstructorResolver#autowireConstructor()方法:
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// 如果指定了构造方法参数,那么直接使用指定的参数
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// 如果没有,从各种途径获取参数
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 看看有没有构造方法
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 先在BeanDefinition中已解析的找一找
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 没找到,那么将这个构造方法设为预解析的
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果需要预解析,解析对应的参数
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
// 如果现在还没找到构造方法
if (constructorToUse == null) {
// 那么需要解析一个构造方法
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 如果存在指定的构造方法
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
...
}
// 找到了符合条件的构造方法集合
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// 如果找到了最合适的构造方法,那就出去吧
break;
}
if (paramTypes.length < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
// 构造对应参数类型的参数
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
// 根据名称和类型创建参数的持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
...
}
else {
// 最起码构造参数的个数得相同吧
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 选择最符合匹配规则的构造方法
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
...
if (explicitArgs == null) {
// 将解析的构造函数假如缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
//
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
}
}, beanFactory.getAccessControlContext());
}
else {
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setBeanInstance(beanInstance);
return bw;
}
...
}
这么打一段代码,在本系列文章中,第一次遇到,不同情况完全没有任何拆分,一步到位,极大的加重了理解难度,照例,我们撸一下思路:
- 根据情况不同,获取构造方法的参数。
- 根据构造方法的参数数量锁定构造方法。
- 根据构造方法转换参数类型。
- 由于可能会出现String str = “1”,但却识别为int类型的情况,Spring在结尾处又做了一层校验。
- 根据构造方法实例化Bean,返回对象。
梳理一下,还是很好理解的,好了到此为止,好的代码不是让大家抄袭的,是让大家理解的,笔者认为这段代码完全没有学习的必要,感觉像是根据需求不断迭代,没有进行过重构似的。
无参实例化
看了上面超级复杂的有参构造方法注入,我们看一下无参的注入,AbstractAutowireCapableBeanFactory#instantiateBean():
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
...
}
很简单,直接调用实例化方法即可。
实例化方法
在以上两种实例化策略中,最后都是通过实例化方法生产实例对象,现在我们就来看看实例化方法究竟干了些什么,SimpleInstantiationStategy#instantiate():
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// 没有任何重载机制
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
// 锁住构造方法参数,获取对应的构造方法
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
...
}
}
// 根据构造方法进行实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 如果存在重载机制,那么就需要CGLIB的帮忙了
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
我们重点看看两个实例化方法。
首先,BeanUtils#instantiateClass():
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
}
...
}
直接通过反射返回对象实例。
接着,CglibSubclassingInstantiationStategy#instantiateWithMethodInjection():
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
继续往下走,CglibSubclassingInstantiationStategy#instantiateWithMethodInjection():
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) {
// 通过CGLIB动态代理进行实例化
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
创建CGLIB动态代理对象来实例化,CglibSubclassCreator是CglibSubclassingInstantiationStrategy的内部类,继续往下走CglibSubclassingInstantiationStategy#instantiate():
public Object instantiate(Constructor<?> ctor, Object... args) {
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
// 没有构造方法
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
// 有构造方法
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
...
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
// 为了避免内存泄露,所以不将这些look-up method或者是replace method放在代理类中,而是放在实例中
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
根据构造方法的有无,分别通过代理类型进行实例化。
到这里,是不是已经忘记从哪里来的了?是这样,我们是从createBean中的createBeanInstance拐到这里来的,复习一下之前的代码,AbstractAutowireCapableBeanFactory#doCreateBean():
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 首先看下实例缓存中有没有Bean,如果有,移除。
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果没有,创建一个新实例
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 锁住后置处理
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 进行各种类型的后置处理,aop就是在这里织入的
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
...
mbd.postProcessed = true;
}
}
// 看看是否需要放入到ObjectFactory缓存中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 放入ObjectFactory缓存中
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Bean实例化
Object exposedObject = bean;
try {
// 属性注入
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
...
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
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);
}
}
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.");
}
}
}
}
//
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
...
return exposedObject;
}
创建完Bean实例后,如果符合放入ObjectFactory缓存中的条件,那么就放在ObjectFactory中。
实例化后,这个实例是空的,所以我们接下来就需要AbstractAutowireCapableBeanFactory#populateBean()方法提供的属性注入:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
// 如果Bean实例为空,无法注入
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
// 给各种Bean的后置处理器最后一个机会来改变Bean
// 支持属性注入
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名字注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据类型注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 后置处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 对所有需要依赖检查的属性进行后置处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依赖检查,Spring 3.0后已经废弃,Sring 2.0中对应属性dependency-check
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 将属性设置到Bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
对于现阶段的Spring版本来说,这段代码主要是自动注入,设置属性到Bean实例中。
自动注入分为两种,根据名字进行注入和根据类型进行注入。
- 根据名字自动注入。
protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (containsBean(propertyName)) { Object bean = getBean(propertyName); pvs.add(propertyName, bean); registerDependentBean(propertyName, beanName); if (logger.isDebugEnabled()) { logger.debug("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } } }
根据传入的属性名称找到对应的Bean,添加到pvs中。
- 根据类型自动注入
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); // 获取需要注入属性的名字 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { // 获取属性描述符 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. if (Object.class != pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // 如果允许优先级解析,那么就不允许提前解析 boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass()); // 获取需要注入的依赖的描述器 DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 根据相关信息获取解析参数 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { // 添加到pvs中 pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { // 注册依赖Bean registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
根据类型自动注入最后是注入的是resolveDependency()解析出来的对象参数,我们来看一下是如何进行解析的:
@Override public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } }
从解析策略可以看出,都是根据依赖描述器已经相关的BeanName获取最后的注入参数,我们继续看DefaultListableBeanFactory#doResolveDependency():
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } Class<?> type = descriptor.getDependencyType(); // @Value注解 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { // 如果必须有这个属性,但是匹配到的Bean为空,那么报出异常 if (descriptor.isRequired()) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; if (matchingBeans.size() > 1) { autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (descriptor.isRequired() || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(type, matchingBeans); } else { return null; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { // 如果只有一个符合的元素 Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { autowiredBeanNames.add(autowiredBeanName); } return (instanceCandidate instanceof Class ? descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate); } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
先直接解析@Value注解的属性,然后再去获取相应匹配的Bean,如果匹配到多个Bean,如果!(type.isArray() || (type.isInterface() &&(Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type))))或是这个依赖必须有,那么使用自定义的解析器,如果没有,我理解的意思是,Spring也不帮你解决这些烂七八糟的玩意。如果只有一个符合条件的参数,那么直接添加到pvs中即可。
- 将解析后的值放入到BeanInstance中,AbstractAutowireCapableBeanFactory#applyPropertyValues()。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { // 为了避免运行时引用过程中出现的问题,Spring采用了深度拷贝的方法 if (pvs == null || pvs.isEmpty()) { return; } MutablePropertyValues mpvs = null; List<PropertyValue> original; // 设置安全机制 if (System.getSecurityManager() != null) { if (bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } } // 如果属性集合属于可转变的集合 if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { // 如果属性值已经转换为对应的类型,那么直接放入到BeanWrapper中 try { bw.setPropertyValues(mpvs); return; } ... } } original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); } // 获取自定义类型转换器 TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // 声明一个属性列表的深拷贝对象 List<PropertyValue> deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false; for (PropertyValue pv : original) { // 如果类型已经转换完成,直接加入到列表中 if (pv.isConverted()) { deepCopy.add(pv); } else { // 如果还没有进行类型转换,进行类型转换 String propertyName = pv.getName(); Object originalValue = pv.getValue(); Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // 防止再转换 if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } // 集合里面的属性已经全部进行类型转换后,请周知 if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } // 属性已经符合要求了,将处理后的属性放入到BeanWrapper中 try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } ... }
总结一下:
- 首先判断属性集合是不是可变集合类型。如果是,那么检查集合中的属性是不是都已经对应正确的类型。如果是那么直接放入到BeanWrapper中。如果不是,放入到默认容器中等待下一步处理。如果不是,直接放入到默认容器中等待下一步处理。
- 声明解析器,根据容器中属性类型的不同,对每个属性进行扶正。
- 类型转换后,这个容器中的所有属性都符合正常要求了,以后就不需要重新进行转换了。
- 将最终的属性集合放入到BeanWrapper中。
到这里属性注入就结束了。
Bean实例化
属性注入后,如果一个Bean允许提前暴露给开发者,那么就需要进行实例化。我们需要复习一下之前的代码,AbstractAutowireCapableBeanFactory#doCreateBean():
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
}
如果当前Bean不为空,直接实例化gogogo,AbstractAutowireCapableBeanFactory#initializeBean():
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 安全机制检查
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// 实现一些Aware接口方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 前置处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 实现方法调用
invokeInitMethods(beanName, wrappedBean, mbd);
}
...
if (mbd == null || !mbd.isSynthetic()) {
// 后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
我们看一下实现方法调用的实现,AbstractAutowireCapableBeanFactory#invokeInitMethods():
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
// 判断是不是InitializingBean,如果是,需要对属性进行后处理
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
...
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
// 如果BeanDefinition不为空,则调用自定义实现的方法
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
首先我们来看看属性的后处理干了些什么,AbstractFactoryBean#afterPropertiesSet():
@Override
public void afterPropertiesSet() throws Exception {
if (isSingleton()) {
this.initialized = true;
this.singletonInstance = createInstance();
this.earlySingletonInstance = null;
}
}
单例的情况下设置已经实例化,创建一个单例实例,并将预创建对象设置为空。
接下来我们看一下如何调用自定义实现的方法,AbstractAutowireCapableBeanFactory#invokeCustomInitMethod():
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
// 获取需要调用的方法
String initMethodName = mbd.getInitMethodName();
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
// 如果没有需要调用的方法
if (initMethod == null) {
// 必须有实现的方法,抛出异常
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Couldn't find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
// 没有强制措施,略过吧
else {
if (logger.isDebugEnabled()) {
logger.debug("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
return;
}
}
if (logger.isDebugEnabled()) {
logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
// 安全措施检查
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
ReflectionUtils.makeAccessible(initMethod);
return null;
}
});
try {
// 在安全方式中进行方法调用
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
initMethod.invoke(bean);
return null;
}
}, getAccessControlContext());
}
...
}
else {
try {
// 通过反射调用对应Bean的方法
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
}
...
}
}
如果进行反射调用的呢,Method#invoke():
@CallerSensitive
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor;
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
直接根据方法的反射方式进行调用。
注册DisposableBean
DisposableBean主要用Bean的销毁,比如说我们配置了destroy-method属性,也可以通过DestuctionAwareBeanPostProcessor来同意销毁Bean,我们来看看创建Bean过程中是如何向销毁池中注册Bean的,AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary():
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
这看起来很复杂,其实很简单,总结一下:
- 如果Bean是单例Bean,那么直接放入到销毁缓存中(LinkedHashMap)。
- 如果不是单例Bean,那么调用相应类型的销毁策略。
获取Bean
这个内部类感觉信息量爆炸,我们绕了很久终于绕了出来,创建完成之后我们肯定是获取这个Bean了,直接进入这个获取实现内部看一看,DefaultSingletonBeanRegistry#getSingleton():
public Object getSingleton(String beanName, ObjectFactory\<?\> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
...
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
总结一下:
- 去缓存中获取Bean。
- 如果没有,去ObjectFactory中获取Bean。
- 如果是一个新Bean,添加到缓存中。
AbstractBeanFactory#getObjectForBeanInstance()之前已经领读过,再次不再赘述,请忘情翻阅。
这样,创建并获取单例Bean就完成了。