文章目录
- BeanFactory
- HierarchicalBeanFactory
- ConfigurableBeanFactory
- AbstractBeanFactory
- AbstractBeanFactory#doGetBean
- DefaultSingletonBeanRegistry#getSingleton
- AbstractAutowireCapableBeanFactory#createBean
- AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
- BeanWrapper
- AbstractAutowireCapableBeanFactory#doCreateBean
- AbstractAutowireCapableBeanFactory#createBeanInstance
- ConstructorResolver#autowireConstructor
- AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
- AbstractAutowireCapableBeanFactory#populateBean
- AbstractAutowireCapableBeanFactory#initializeBean
- AbstractAutowireCapableBeanFactory
- DefaultListableBeanFactory
- ConfigurableListableBeanFactory
- AutowireCapableBeanFactory
- ListableBeanFactory
- StaticListableBeanFactory
- AutowireCapableBeanFactory
- SingletonBeanRegistry
- AliasRegistry
- bean容器的启动阶段
- 容器中bean的实例化阶段
- 总结
- 依赖注入(DI)
BeanFactory
说到Spring框架,人们往往大谈特谈一些似乎高逼格的东西,比如依赖注入,控制反转,面向切面等等。但是却忘记了最基本的一点,Spring的本质是一个bean工厂(beanFactory)或者说bean容器,它按照我们的要求,生产我们需要的各种各样的bean,提供给我们使用。只是在生产bean的过程中,需要解决bean之间的依赖问题,才引入了依赖注入(DI)这种技术。也就是说依赖注入是beanFactory生产bean时为了解决bean之间的依赖的一种技术而已。
那么我们为什么需要Spring框架来给我们提供这个beanFactory的功能呢?原因是一般我们认为是,可以将原来硬编码的依赖,通过Spring这个beanFactory这个工长来注入依赖,也就是说原来只有依赖方和被依赖方,现在我们引入了第三方——spring这个beanFactory,由它来解决bean之间的依赖问题,达到了松耦合的效果;这个只是原因之一,还有一个更加重要的原因:在没有spring这个beanFactory之前,我们都是直接通过new来实例化各种对象,现在各种对象bean的生产都是通过beanFactory来实例化的,这样的话,spring这个beanFactory就可以在实例化bean的过程中,做一些小动作——在实例化bean的各个阶段进行一些额外的处理,也就是说beanFactory会在bean的生命周期的各个阶段中对bean进行各种管理,并且spring将这些阶段通过各种接口暴露给我们,让我们可以对bean进行各种处理,我们只要让bean实现对应的接口,那么spring就会在bean的生命周期调用我们实现的接口来处理该bean。
BeanFactory属于Spring的核心接口,提供了高级IOC的配置机制,BeanFactory是框架的基本设施,面向spring本身,BeanFactory在启动容器时,并不会初始化配置文件中定义的Bean,初始化发生在第一次调用,对于单例的Bean,BeanFactory会缓存在Bean实例,所以在第二次使用时,直接从缓存中获取Bean实例。
public interface BeanFactory {
///对FactoryBean转义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象
String FACTORY_BEAN_PREFIX = "&";
//通过名称获取bena实例
Object getBean(String name) throws BeansException;
//按照类象获得Bean,requiredType可以是父类
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
//按照给定的参数创建bean实例(仅在创建新实例时才应用,而不是在检索现有实例时应用)
Object getBean(String name, Object... args) throws BeansException;
//根据类型获得Bean
<T> T getBean(Class<T> requiredType) throws BeansException;
//按照给定的参数创建对应的Bean(仅在创建新实例时才应用,而不是在检索现有实例时应用)
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
//根据name判断,是否含有某个Bean
boolean containsBean(String name);
//是否单例Bean
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//是否为原型Bean
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
//检查bean是否和给定的类型匹配
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
//获取Bean的Calss类型
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
//获取Bean别名
String[] getAliases(String name);
}
HierarchicalBeanFactory
这个工厂接口非常简单,实现了Bean工厂的分层。这个工厂接口也是继承自BeanFacotory,也是一个二级接口,相对于父接口,它只扩展了一个重要的功能——工厂分层。
父子级联IOC容器接口,子容器可以访问父容器中的Bean,但是父容器不能访问子容器中的Bean,在同一个容器中Bean的id时唯一的,但在父子容器中子容器可以拥有一个和父容器id相同的Bean
public interface HierarchicalBeanFactory extends BeanFactory {
//第一个方法返回本Bean工厂的父工厂。这个方法实现了工厂的分层。
BeanFactory getParentBeanFactory();
//第二个方法判断本地工厂是否包含这个Bean(忽略其他所有父工厂)。这也是分层思想的体现。
boolean containsLocalBean(String name);
}
ConfigurableBeanFactory
ConfigurableBeanFactory定义BeanFactory的配置.ConfigurableBeanFactory中定义了太多太多的api,比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory,bean如何销毁.
ConfigurableBeanFactory同时继承了HierarchicalBeanFactory 和 SingletonBeanRegistry 这两个接口,即同时继承了分层和单例类注册的功能。
- 2个静态不可变常量分别代表单例类和原型类。
- 1个设置父工厂的方法,跟HierarchicalBeanFactory接口的getParentBeanFactory方法互补。
- 4个跟类加载器有关的方法:get/set工厂类加载器和get/set临时类加载器。
- 2个设置、是否缓存元数据的方法(热加载开关)。
- 11个处理Bean注册、加载等细节的方法,包括:Bean表达式分解器、转换服务、属性编辑登记员、属性编辑器、属性编辑注册器、类型转换器、嵌入式的字符串分解器
- 2个处理Bean后处理器的方法。
- 3个跟注册范围相关的方法。
- 1个返回安全访问上下文的方法、1个从其他的工厂复制相关的所有配置的方法。
- 2个跟Bean别名相关的方法、1个返回合并后的Bean定义的方法。
- 1个判断是否为工厂Bean的方法、2个跟当前Bean创建时机相关的方法。
- 3个跟Bean依赖相关的方法、3个销毁Bean相关的方法。
总结:这个巨大的工厂接口,继承自HierarchicalBeanFactory 和 SingletonBeanRegistry 这两个接口,并额外独有37个方法。这37个方法包含了工厂创建、注册一个Bean的众多细节。这个工厂名为ConfigurableBeanFactory,真是名不虚传!统计一下此时的ConfigurableBeanFactory的方法数吧。自有的37个方法、HierarchicalBeanFactory的2个方法、SingletonBeanRegistry的5个方法、爷爷接口BeanFactory的10个方法,共有54个方法!虽然方法繁多,还算井井有条!
/**
* 定义BeanFactory的配置.
*
* 这边定义了太多太多的api,比如类加载器,类型转化,属性编辑器,BeanPostProcessor,
* 作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory,bean如何销毁.
*
*/
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
// 定义了两个作用域: 单例和原型.可以通过registerScope来添加.
// SCOPE_SINGLETON,SCOPE_PROTOTYPE
// 单例
String SCOPE_SINGLETON = "singleton";
// 原型
String SCOPE_PROTOTYPE = "prototype";
// 父容器设置.而且一旦设置了就不让修改
/*
* 搭配HierarchicalBeanFactory接口的getParentBeanFactory方法
*/
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
// 类加载器设置与获取.默认使用当前线程中的类加载器
/*
* 设置、返回工厂的类加载器
*/
void setBeanClassLoader(ClassLoader beanClassLoader);
// 类加载器设置与获取.默认使用当前线程中的类加载器
ClassLoader getBeanClassLoader();
// 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器
/*
* 设置、返回一个临时的类加载器
*/
void setTempClassLoader(ClassLoader tempClassLoader);
// 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器
ClassLoader getTempClassLoader();
// 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存
/*
* 设置、是否缓存元数据,如果false,那么每次请求实例,都会从类加载器重新加载(热加载)
*/
void setCacheBeanMetadata(boolean cacheBeanMetadata);
// 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存
// 是否缓存元数据
boolean isCacheBeanMetadata();
// 定义用于解析bean definition的表达式解析器
/*
* Bean表达式分解器
*/
void setBeanExpressionResolver(BeanExpressionResolver resolver);
// 定义用于解析bean definition的表达式解析器
BeanExpressionResolver getBeanExpressionResolver();
// 类型转化器
/*
* 设置、返回一个转换服务
*/
void setConversionService(ConversionService conversionService);
// 类型转化器
ConversionService getConversionService();
// 属性编辑器
/*
* 设置属性编辑登记员...
*/
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
// 属性编辑器
/*
* 注册常用属性编辑器
*/
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
// 属性编辑器
/*
* 用工厂中注册的通用的编辑器初始化指定的属性编辑注册器
*/
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
// BeanFactory用来转换bean属性值或者参数值的自定义转换器
/*
* 设置、得到一个类型转换器
*/
void setTypeConverter(TypeConverter typeConverter);
// BeanFactory用来转换bean属性值或者参数值的自定义转换器
TypeConverter getTypeConverter();
// string值解析器(想起mvc中的ArgumentResolver了)
/*
* 增加一个嵌入式的StringValueResolver
*/
void addEmbeddedValueResolver(StringValueResolver valueResolver);
boolean hasEmbeddedValueResolver();
// string值解析器(想起mvc中的ArgumentResolver了)
//分解指定的嵌入式的值
String resolveEmbeddedValue(String value);
// BeanPostProcessor用于增强bean初始化功能
//设置一个Bean后处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
//返回Bean后处理器的数量
int getBeanPostProcessorCount();
// 作用域定义
//注册范围
void registerScope(String scopeName, Scope scope);
// 作用域定义
//返回注册的范围名
String[] getRegisteredScopeNames();
// 作用域定义
//返回指定的范围
Scope getRegisteredScope(String scopeName);
// 访问权限控制
//返回本工厂的一个安全访问上下文
AccessControlContext getAccessControlContext();
// 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等
//从其他的工厂复制相关的所有配置
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
// bean定义处理,注册别名
/*
* 给指定的Bean注册别名
*/
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
// bean定义处理
//根据指定的StringValueResolver移除所有的别名
void resolveAliases(StringValueResolver valueResolver);
// bean定义处理
// 合并bean定义,包括父容器的
/*
* 返回指定Bean合并后的Bean定义
*/
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// bean定义处理
// 是否是FactoryBean类型
//判断指定Bean是否为一个工厂Bean
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
// bean创建状态控制.在解决循环依赖时有使用
//设置一个Bean是否正在创建
void setCurrentlyInCreation(String beanName, boolean inCreation);
// bean创建状态控制.在解决循环依赖时有使用
//返回指定Bean是否已经成功创建
boolean isCurrentlyInCreation(String beanName);
// 处理bean依赖问题
//注册一个依赖于指定bean的Bean
void registerDependentBean(String beanName, String dependentBeanName);
// 处理bean依赖问题
//返回依赖于指定Bean的所欲Bean名
String[] getDependentBeans(String beanName);
// 处理bean依赖问题
//返回指定Bean依赖的所有Bean名
String[] getDependenciesForBean(String beanName);
// bean生命周期管理-- 销毁bean
//销毁指定的Bean
void destroyBean(String beanName, Object beanInstance);
// bean生命周期管理-- 销毁bean
//销毁指定的范围Bean
void destroyScopedBean(String beanName);
// bean生命周期管理-- 销毁bean
//销毁所有的单例类
void destroySingletons();
}
AbstractBeanFactory
主要提供:类别名管理,单例生命周期管理,工厂方法初始化类对应的FactoryBean,BeanFactory容器
//BeanFactory的抽象实现.
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
// code
}
通过之前跟踪Spring IOC刷新的源码,我们所有的剩余的单例Bean都是通过这一步:finishBeanFactoryInitialization(beanFactory);来进行初始化的。最重要的一个方法就为:DefaultListableBeanFactory#preInstantiateSingletons,其内部核心方法为:getBean --> doGetBean方法
getBean()是顶层接口BeanFactory提供的,一共有五个原型:
Object getBean(String name) throws BeansException;
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
// Spring2.5以后才有的接口
Object getBean(String name, Object... args) throws BeansException;
// Spring3.0以后才有的接口
<T> T getBean(Class<T> requiredType) throws BeansException;
// Spring4.1以后才有的接口
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
说明:很多人都不理解这个args是干什么用的,这里解释一下。首先我们要明白,getBean()内部不仅仅是get,如果get不到还可能去实例化一个Bean的(默认根据空构造函数进行实例化),因此本处的args其实就是为了匹配构造函数而提供的扩展功能~
AbstractBeanFactory作为抽象实现,复写了其中3个方法:
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
// 备注:此处的doGetBean,就是Bean实例化的核心逻辑
DefaultListableBeanFactory继承自AbstractBeanFactory,复写了剩余的2个方法:
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
// 上面那个方法是调用这个方法的逻辑。
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {]
// resolveNamedBean里面的逻辑,也是根据requiredType去找的。若不止一个会抛错:NoUniqueBeanDefinitionException
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
// 从这里我们可以看到,如果子容器里没有找到Bean,还回去父容器(若存在的话)里找找看
BeanFactory parent = getParentBeanFactory();
if (parent != null) {
return (args != null ? parent.getBean(requiredType, args) : parent.getBean(requiredType));
}
throw new NoSuchBeanDefinitionException(requiredType);
}
那么接下里,我们就得看看这里面最最核心的逻辑:doGetBean()
AbstractBeanFactory#doGetBean
依赖注入主要有两个过程,一个是实例化Bean,另一个是将依赖关系注入到Bean中
从命名上我们也可以看出:他是doGetBean,是有do这个动作的。因此不是简单的get有就返回,没有就返回null这么简单的操作。而是里面做了实例化、依赖注入、属性赋值、解决循环依赖等一些列操作~
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 该方法作用:1、 如果是FactoryBean,会去掉Bean开头的&符号
// 2、能存在传入别名且别名存在多重映射的情况,这里会返回最终的名字,如存在多层别名映射A->B->C->D,传入D,最终会返回A
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// getSingleton()方法的实现,在父类DefaultSingletonBeanRegistry中
//这里先尝试从缓存中获取,若获取不到,就走下面的创建
// 特别注意的是:这里面走创建(发现是个new的),就加入进缓存里面了 if (newSingleton) {addSingleton(beanName, singletonObject);} 缓存的字段为全局的Map:singletonObjects
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
// 这里虽然只是一句日志,但是能说明用意。
// 若条件为true,表示这个Bean虽然在缓存里,但是还并没有完全被初始化(循环引用)
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 在getBean方法中,getObjectForBeanInstance是个频繁使用的方法。因此为了更好的知道细节,下面会详解这个方法的
// 其实简单理解就是处理FactoryBean的getObject()方法
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 原型对象不允许循环创建,如果是原型对象正在创建,那就抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 这一步也是必须要做的,若存在父容器,得看看父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准)
// 这就是为何,我们扫描controller,哪怕不加排除什么的,也不会出问题的原因~,因为Spring中的单例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 {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//alreadyCreated字段增加此值。表示此Bean已经创建了
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 根据名字获取合并过的对应的RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查mbd是否为抽象的或mbd为单例,但存在args的情况(args只有初始化原型对象才允许存在)
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 这里就重要了,因为我们会有属性注入等等 所以这里就是要保证它依赖的那些属性先初始化才行
// 这部分是处理循环依赖的核心,这里稍微放一放。下面有大篇幅专门讲解这方面的以及原理解决方案
// @DependsOn注解可以控制Bean的初始化顺序~~~
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);
}
}
}
// Create bean instance.
// 从这里开始,就正式开始着手创建这个Bean的实例了~~~~
if (mbd.isSingleton()) {
// 也是一样先尝试从缓存去获取,获取失败就通过ObjectFactory的createBean方法创建
// 这个getSingleton方法和上面是重载方法,它支持通过ObjectFactory去根据Scope来创建对象,具体源码解析见下面
sharedInstance = getSingleton(beanName, () -> {
try {
// 这是创建Bean的核心方法,非常重要,是抽象方法,由子类去实现
// AbstractAutowireCapableBeanFactory#createBean实现了此抽象方法
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 执行失败,就销毁Bean。然后执行对应的destroy方法,等等销毁Bean时候的生命周期方法们~~~~~~~~~这个就不多说了 主要看看上面的createBean方法吧
destroySingleton(beanName);
throw ex;
}
});
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, () -> {
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;
}
}
// Check if required type matches the type of the actual bean instance.
// 这里就比较简单了,就是requiredType,比如要求是Integer,获得的是String,俺么就会调用转换器转换过来
// 绝大多数情况下,没啥卵用
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
DefaultSingletonBeanRegistry#getSingleton
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 此处是先从已经缓存好了的singletonObjects的Map中,查看有木有(至于当前已经有哪些了,下面有个截图,相信什么时候进来的都应该有些印象吧)
Object singletonObject = this.singletonObjects.get(beanName);
// 若缓存里没有。并且,并且,并且这个Bean必须在创建中,才会进来。
// singletonsCurrentlyInCreation字段含义:会缓存下来所有的正在创建中的Bean,如果有Bean是循环引用的 会把这种Bean先放进去,这里才会有值
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;
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 从缓存中获取(上面获取过一次的,这里是双从判定)
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 如果这个Bean正在被销毁,就抛异常了
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!)");
}
// 创建前置检查:1、若在inCreationCheckExclusions面校验名单里,是ok的
//2、singletonsCurrentlyInCreation把它添加进去,证明这个Bean正在创建中
beforeSingletonCreation(beanName);
// 此处先打标机为为false
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 把这个实例生成出来,并且标志位设为true
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
// in the meantime再次旗舰,若有人已经把这个Bean放进去了,那就抛出这个异常吧
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
// 处理异常
// 比如我们经常遇到的UnsatisfiedDependencyException异常:@Autowired的时候找不到依赖的Bean就是这个异常(一般由NoSuchBeanDefinitionException这个异常导致)
// 这里会吧异常链接拼接起来,然后一起打印出来~~~~非常方便查找问题
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 创建完成后再检查一遍。做的操作为:从正在创建缓存中移除
afterSingletonCreation(beanName);
}
// 这里也非常重要:若是新的Bean,那就执行addSingleton这个方法,这个方法做了什么,就下面4步操作:
//this.singletonObjects.put(beanName, singletonObject); //缓存起来
//this.singletonFactories.remove(beanName); //把对应ObjectFactory的缓存移除
//this.earlySingletonObjects.remove(beanName);
//this.registeredSingletons.add(beanName);
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
AbstractAutowireCapableBeanFactory#createBean
抽象方法AbstractBeanFactory#createBean由子类AbstractAutowireCapableBeanFactory#createBean提供实现。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
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.
// 确保对应BeanClass完成解析(已经加载进来了Class对象)具体表现是进行了ClassLoder.loadClass或Class.forName完成了类加载
// 主要根据传入的typesToMatch生成特定的ClassLoader,之后还要调用RootBeanDefinition#resolveBeanClass,
// 根据特定的加载器或者默认加载器加载出class属性对应的Class对象
// 我们这里解析出来,显然就是class com.fsx.service.HelloServiceImpl这个Class了
// 判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入(也就说它甚至可能来源于网络)
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 这里主要是解析<lookup-method name="getFruit" bean="bananer"/>类似这种方式
// 的依赖注入(Spring支持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.
// 从doc解释:给BeanPostProcessors一个机会来返回一个代理对象代替目标对象,什么动态代理之类的,都在这里实现的
// 1、具体逻辑是判断当前Spring容器是否注册了实现了InstantiationAwareBeanPostProcessor接口
// 的后置处理器如果有,则依次调用其中的applyBeanPostProcessorsBeforeInstantiation方法,
// 如果中间任意一个方法返回不为null,直接结束调用。
// 2、然后依次所有注册的BeanPostProcessor的postProcessAfterInitialization
// 方法(同样如果任意一次返回不为null,即终止调用)
// 这个方法也非常的重要,后续有详细讲解
// 容器里所有的InstantiationAwareBeanPostProcessors实例,都会在此处生效,进行前置处理
// 下面有解释:BeanPostProcessor和InstantiationAwareBeanPostProcessor的区别,可以分清楚他们执行的时机
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 {
// 这里又是一个核心逻辑:doCreateBean 创建Bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
// 创建完成后 直接短路掉返回
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);
}
}
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved 这个属性如果是false,表示不需要被前置处理了
// 然后,唯一能改变它的值的地方,是下面这仅仅一行代码而已,它的访问权限为package
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 这里hasInstantiationAwareBeanPostProcessors()方法就是看属性hasInstantiationAwareBeanPostProcessors的值。
// 就是标记容器里是否有InstantiationAwareBeanPostProcessor的实现
// 显然,在执行addBeanPostProcessor,发现这个Bean是这个子类型的时候,就会设为true了。
// 同理的还有hasDestructionAwareBeanPostProcessors这个属性,表示销毁的处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 拿到最终的目标类型(放置被别的包装过)显然此处是;com.fsx.service.HelloServiceImpl
// 可能依赖于AbstractBeanFactory#resolveBeanClass这个方法去解析
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 先执行执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回调方法
// 里面的逻辑也比较简单:拿到缓存好的(List装着的)所有的BeanPostProcessors,
// 如果是InstantiationAwareBeanPostProcessor就执行吧
// 只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要)
// 1.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor这个内部类就是这个类型。
// 主要还是去增强、完善处理@Configuration这种类,但是它并没有重写postProcessBeforeInstantiation这个方法,
// 所以默认是返回null的
// 2.CommonAnnotationBeanPostProcessor/Autowired也没做处理(若你自己不去注册,那系统里就再没有了)
// 需要注意的是,如果我们采用了AOP、声明式事务等等,这里就会有了,后面又会回来讲解这一块
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 我们可以看到,如果bean不为null,那就直接返回了 短路掉后面的After也就不执行了
if (bean != null) {
// 注意,这里是Initialization,是初始化的后置方法,是BeanPostProcessor的方法,
// 也就是说初始化完成后的方法。
// 为何这里执行这个方法呢?是因为我们上面说了,如果返回不为null,后面都都会被短路掉。
// 但是此处Spring还是让我们执行了初始化后的处理器方法,这点需要引起注意
// 就是说:即使Bean在实例化前已经返回了一个不为null的对象,别的方法都被短路了,
// 但是我的【初始化】后处理器方法applyBeanPostProcessorsAfterInitializationh还是可以执行的
// 这里面可以关注一下这个类:ApplicationListenerDetector
// 初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了==============
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
BeanPostProcessor和InstantiationAwareBeanPostProcessor(SmartInstantiationAwareBeanPostProcessor)这两个接口,是比较容易搞混的,需要这里注意区分一下。InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:
- 实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中
- 初始化:初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性
所以现在就清楚了:InstantiationAwareBeanPostProcessor是作用于实例化前后,所以是先执行的。BeanPostProcessor是作用于初始化 前后,给Bean各个属性赋值的时候执行的(比如我们的属性依赖注入,都是这个时候生效的)
// 咋一看,以为方法名都一样?哈哈 其实你区分出来两个单词的意思,就明白了
// Instantiation:[ɪnstænʃɪ'eɪʃən] 实例化,例示
// Initialization:[ɪˌnɪʃəlaɪ'zeɪʃn] 初始化,设定初始值
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
稍微总结下:
- InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置。
- postProcessBeforeInstantiation方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走。
- postProcessAfterInstantiation方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行。
- postProcessPropertyValues方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改。
- 父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的。
BeanWrapper
BeanWrapper 是Spring提供的一个用来操作javaBean属性的工具,使用它可以直接修改一个对象的属性。
BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性。用户很少需要直接使用BeanWrapper进行编程。
对于bean属性的操作,我们熟知的主要有下面这些工具类:
- Apache的BeanUtils和PropertyUtils
- cglib的BeanMap和BeanCopier
- spring的BeanUtils
Spring中BeanWrapper 的主要在于如下三点:
1· 支持设置嵌套属性
2. 支持属性值的类型转换(设置ConversionService)
3. 提供分析和操作标准JavaBean的操作:获取和设置属性值(单独或批量),获取属性描述符以及查询属性的可读性/可写性的能力
public interface BeanWrapper extends ConfigurablePropertyAccessor {
//为数组和集合自动增长指定一个限制。在普通的BeanWrapper上默认是无限的。
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
//返回数组和集合自动增长的限制。
int getAutoGrowCollectionLimit();
//如果有的话,返回由此对象包装的bean实例
Object getWrappedInstance();
//返回被包装的JavaBean对象的类型。
Class<?> getWrappedClass();
//获取包装对象的PropertyDescriptors(由标准JavaBeans自省确定)。
PropertyDescriptor[] getPropertyDescriptors();
//获取包装对象的特定属性的属性描述符。
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
}
BeanWrapperImpl是Spring提供的唯一实现类。具体此处不深究了,知道它是Spring用来统一处理Bean的就成了
AbstractAutowireCapableBeanFactory#doCreateBean
创建Bean的最终方法,绝大多数Bean的实例化、初始化都会走这里
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 用BeanWrapper来持有创建出来的Bean对象
BeanWrapper instanceWrapper = null;
// 如果是单例的话,则先把缓存中的同名bean清除(同名的)
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 实际创建的交给createBeanInstance来完成,
// bean的生成,这里会使用默认的类生成器,包装成BeanWrapperImpl类,
// 为了下面的populateBean方法的属性注入做准备
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
// 如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 此处处理这个接口的处理器:MergedBeanDefinitionPostProcessor,
// 他在BeanPostProcessor的基础上增加了postProcessMergedBeanDefinition方法,在此处就被调用了
// 主要是处理@PostConstruct,@Autowire,@Value,@Resource,@PreDestory等这些注解。
// (显然对应哪去处理器,一目了然了) 下面会举例看看AutowiredAnnotationBeanPostProcessor的处理
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.
// 如果当前bean是单例,且支持循环依赖,且当前bean正在创建,通过往singletonFactories添加一个objectFactory,
// 这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean
// getEarlyBeanReference可以对返回的bean进行修改,这边目前除了可能会返回动态代理对象 其他的都是直接返回bean
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");
}
// 这里面主要是解决循环引用问题,借助了这个工厂
// 这里主要是调用处理器:SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法去
// 寻找到前期的Bean们(若存在这种处理器的话)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
// 这个Obj,就是最终要返回的对象了
Object exposedObject = bean;
try {
// 这又是非常非常重要的一步:给已经初始化的属性们赋值,对bean进行填充,在这里面完成依赖注入的相关内容
populateBean(beanName, mbd, instanceWrapper);
//完成属性依赖注入后,进一步初始化Bean 具体进行了以下操作:
//若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
//遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
//如果实现了initialzingBean,调用实现的 afterPropertiesSet()
//如果配置了init-mothod,调用相应的init方法
//遍历后置处理器,调用实现的postProcessAfterInitialization
// 关于populateBean和initializeBean的详解,下贴出了博文链接参考~~~~~~
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);
}
}
// 如果earlySingletonExposure为true,尝试从缓存获取该bean(一般存放在singletonFactories
// 对象通过调用getObject 把对象存入earlySingletonObjects),
// 分别从singletonObjects和earlySingletonObjects获取对象,这里依然是处理循环依赖相关问题的
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.");
}
}
}
}
// Register bean as disposable.
try {
// 如果有需要,就注册DisposableBean,这样Bean销毁的时候此种后置处理器也会生效了
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
AbstractAutowireCapableBeanFactory#createBeanInstance
在 createBeanInstance 中生成了Bean所包含的java对象:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//一样的,确保bean类实际上已经解析过了,可以实例化
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//确保class不为空,并且访问权限为public 所以注意如果你的Class不是public的,Spring给你创建不了对象
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());
}
// 配置的一种特殊的callback回调方法,通过这个callback创建bean
// Supplier返回的Obj,最终会交给obtainFromSupplier包装成BeanWrapper
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 这是Spring支持的又一种方式:使用工厂方法来进行bean的实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
// 此部分在循环依赖中,会有更深入的说明
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 标记一下,已经解析过class的构造器
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// resolved若为true,表示已经解析过构造器了,就下面直接使用解析好的构造器实例化Bean
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
// 通过此方法,去检测到一个可用的构造器:这里面智能使用SmartInstantiationAwareBeanPostProcessor啦,
// 它通过循环调用处理器的determineCandidateConstructors方法,谁第一个发现一个可用的构造器,就return,否则返回null
// 详情见下面讲解AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors方法的讲解
// 这里需要注意:如果你的Bean没有空的构造函数(比如只有一个参数的构造函数,那么Spring会用这个构造函数给你实例化Bean,
并且入参会自动帮你从容器里去找出来)
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
ConstructorResolver#autowireConstructor
这个方法作用是获取被包装后的bean,包装后的对象是BeanWrapper对象,这个对象的实现类是BeanWrapperImpl。其中包含被封装后待处理的bean,和设置bean属性的属性编辑器。
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
// 此处的this,就是DefaultListableBeanFactory嘛
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
// ConstructorResolver#autowireConstructor
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {
//先实例化一个BeanWrapperImpl类对象
BeanWrapperImpl bw = new BeanWrapperImpl();
// initBeanWrapper做了一些事,比如注册解析器、value解析器等等 这是个比较大的概念,后面会有专题再说吧
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//如果构造参数不为空就直接使用这些参数即可
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// 否则构造函数的入参,交给Spring处理。它会去容器里拿~~~~~
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//获取已缓存解析的构造函数或工厂方法(resolvedConstructorOrFactoryMethod----用于缓存已解析的构造函数或工厂方法)
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
////如果缓存不为空,并且构造参数已经解析缓存了,(constructorArgumentsResolved为包可见,用于表示构造参数状态是否已经解析)
// 显然首次进来,都是为null并且没有被解析的
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果上面没有解析过,显然这里参数就是null了,argsToUse也就还为null Spring下面继续解析
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//如果缓存的构造器不存在,就说明没有bean进行过解析,需要去关联对应的bean的构造器
if (constructorToUse == null) {
// Need to resolve the constructor.
// 我们的传值chosenCtors 显然不为null,所以此值为true
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
//若传入的构造参数不为空,那最小参数长度一塔为准
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 这里相当于要解析出构造函数的参数了
//解析对应的构造参数然后添加到ConstructorArgumentValues中
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// Take specified constructors, if any.
//如果传入的构造器为空,则获取bean的Class对象,然后根据bean是不是public修饰的来按照不同的方式获取所有的构造器
// 显然,我们这里(大都都会有构造器)
// 但是此处我们发现,即使构造器不是public的,这里也能够遭到构造器来进行实例化
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
//getDeclaredConstructors返回所有的构造器(包括public和private修饰的),getConstructors返回public修饰的
candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors());
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
// 这个构造器排序有点意思
//按照访问方式和数量对构造器进行排序;public>protect>private,在同为public时构造器入参多的排在前面
// 所以排在第一位的,是public的,参数最多的构造器
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
// 记录下,引起歧义的构造器们。就是记录下来,如果存在这种歧义,抛异常的时候用来告诉调用者
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 开始遍历排序后的构造器了==========================
for (Constructor<?> candidate : candidates) {
// 拿到构造器参数的类型们
Class<?>[] paramTypes = candidate.getParameterTypes();
// constructorToUse不为null(表示已经找到了合适构造器),但是呢,连参数个数的长度都对应不上,那就直接break,后面的构造器全都不用看了
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 如果参数个数比最小个数还小,那就继续下一个构造器吧。
if (paramTypes.length < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
//兼容JDK6提供的@ConstructorProperties这个注解,如果它标注了参数名,那就以它的名字为准
//@ConstructorProperties的作用=======》构造函数上的注解,显示该构造函数的参数如何与构造对象的getter方法相对应
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
// 否则,就自己解析
if (paramNames == null) {
// 一般都是Bean工厂默认的DefaultParameterNameDiscoverer 解析出变量名
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//根据获取到的参数名和已经查到的构造参数和构造参数类型来创建用户创建构造器用的构造参数数组
//这个数组中包含了原始的参数列表和构造后的参数列表,用来对比用
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
} catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
} else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
//lenientConstructorResolution的值ture与false有什么区别:
//这个属性默认值是true,在大部分情况下都是使用[宽松模式],即使多个构造函数的参数数量相同、类型存在父子类、接口实现类关系也能正常创建bean。
// false表示严格模式。与上面相反
// typeDiffWeight:返回不同的个数的权重(权重概念?)
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 根据权重,选择一个最为合适的构造器
if (typeDiffWeight < minTypeDiffWeight) {
// 大都进这里来,然后是木有ambiguousConstructors 的
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 (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
} else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
//下面步骤都是通用的,用上面得到的构造器(无论是从bean对象中获取的还是spring自己构建的)
// 和参数来反射创建bean实例,并放到BeanWrapperImpl对象中然后返回
try {
// 拿到生成Bean实例化策略,默认值为CglibSubclassingInstantiationStrategy 用CGLIB生成子类的方式
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
// 主要就是调用了策略器的instantiate,对Bean进行了最终的实例化
// 此方法为重载方法,此处因为不需要代理,所以执行的直接是SimpleInstantiationStrategy#instantiate
// 到此处,有一个HelloServiceImpl正式创建 然后继续到doCreateBean方法去吧
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setBeanInstance(beanInstance);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
AbstractAutowireCapableBeanFactor#determineConstructorsFromBeanPostProcessors会调用AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors,检测出候选的构造器们(也就是我们常说的:构造器注入)
检测Bean的构造器,可以检测出多个候选构造器,再有相应的策略决定使用哪一个。它将将自动扫描通过@Autowired/@Value注解的构造器从而可以完成构造器注入
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here..
// 检测@Lookup注解,这个注解的注入方式,已经不推荐使用了
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
this.lookupMethodsChecked.add(beanName);
}
// Quick check on the concurrent map first, with minimal locking.
// 先从缓存里去看,有没有解析过此类的构造函数~~~
// 对每个类的构造函数只解析一次,解析完会存储结果,以备下次复用
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
// 为了线程安全,这里继续校验一次
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
// 拿到此Class所有的构造函数们(一般的类都只有一个空的构造函数) 当然我们也可以写多个
rawCandidates = beanClass.getDeclaredConstructors();
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
// 兼容Kotlin类型做的处理
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 遍历处理每个每个构造器
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 找到构造器里有@Aotowaired或者@Value注解的直接信息们
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
if (ann == null) {
// 此方法的目的是拿到目标类:比如若是被cglib代理过的,那就拿到父类(因为cglib是通过子类的形式加强的)
Class<?> userClass = ClassUtils.getUserClass(beanClass);
// 说明确实是被CGLIB代理过的,那就再解析一次 看看父类是否有@Autowaired这种构造器
if (userClass != beanClass) {
try {
Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
} catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 这里是是存在注解标注的这种构造器的
if (ann != null) {
// 这个判断很有必要,表示要求的构造器最多只能有一个
//画外音:@Autowired标注的构造器数量最多只能有一个(当然,required=true的只能有一个,=false的可以有多个)
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//获取autowire注解中required属性值
boolean required = determineRequiredStatus(ann);
// 只有是true,就往下走(默认值为true)
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
// 这样子,这个构造器就是必须的了,记录下来
requiredConstructor = candidate;
}
// 把标注有@Autowired注解的构造器,记录下来,作为候选的构造器
candidates.add(candidate);
}
// 这个就重要了,处理精妙
// 若该构造器没有被标注@Autowired注解,但是它是无参构造器,
// 那就当然候选的构造器(当然是以标注了@Autowired的为准)
else if (candidate.getParameterCount() == 0) {
// 这里注意:虽然把默认的构造函数记录下来了,但是并没有加进candidates里
defaultConstructor = candidate;
}
}
// 若能找到候选的构造器,这里注意,如果仅仅只有一个构造器的情况(没有标注@Autowired注解),
// 这个亏胡原始股false,下面的elseif会处理的。
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
// 这个是candidates里面有值了,并且还没有requiredConstructor (相当于标注了注解@Autowired,
// 但是required=false)的情况下,会把默认的构造函数加进candidates
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
//如果没有默认的无参构造函数,且有@Autowired(required = false)的构造函数,则发出警告信
else if (candidates.size() == 1 && logger.isWarnEnabled()) {
logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 这个意思是:有且仅有一个构造器,并且该构造器的参数大于0个,那就是我们要找的构造器了
// 这种情况,也是平时我们使用得比较多的情况
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// 处理primaryConstructor以及nonSyntheticConstructors 兼容Kotlin一般都达不到
else if (nonSyntheticConstructors == 2 && primaryConstructor != null
&& defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
// 啥构造器都没找到,那就是空数组
else {
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
// 若有多个构造函数,但是没有一个标记了@Autowired,此处不会报错,但是返回null,交给后面的策略处理
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
AbstractAutowireCapableBeanFactory#populateBean
在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean方法完成。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
// 对实例做的一个判空校验
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
//给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
//具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//postProcessAfterInstantiation 这个方法返回true,后面的处理器才会继续执行,
//但凡返回false,后面的就不会再执行了
//并且continueWithPropertyPopulation 打上标记表示false,也就是说后面的属性复制就不会再执行了
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 处理器若告知说不用继续赋值了,那就以处理器的结果为准即可
if (!continueWithPropertyPopulation) {
return;
}
//pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
//本例中,我们的helloServiceImpl的Bean定义里,pvs为null
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml(或者@Bean中)文件中有显式的配置
//如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
// 根据名称进行注入(见下)
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
// 根据类型进行注入(见下)
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
//结合注入后的配置,覆盖当前配置
pvs = newPvs;
}
// 显然hasInstAwareBpps=true,
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否进行依赖检查 默认值就是None 所以此处返回false,表示不需要依赖检查(关于依赖检查的4种模式,建议使用@Required来显示控制)
//@Required注解作用于Beansetter方法上,用于检查一个Bean的属性的值在配置期间是否被赋予或设置(populated)
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 过滤出所有需要进行依赖检查的属性编辑器
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
// 在这个节点上:调用了InstantiationAwareBeanPostProcessor#postProcessPropertyValues方法,
// 若返回null,整个populateBean方法就结束了=============
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 关于postProcessPropertyValues的实现,有几个处理器是非常关键的:
// 比如AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等等,且看下面的分解
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 若返回null,Spring表示你已经属性值都设置好了,那他也不再管了
if (pvs == null) {
return;
}
}
}
}
// 显然,现在大多数情况下,都不会在check这个了
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
// 注意:这一步完成结束后为止。我们的HelloServiceImpl这个Bean依赖的parent,还只是RuntimeBeanReference类型,还并不是真实的Parent这个Bean
//在Spring的解析段,其它容器中是没有依赖的Bean的实例的,因此这个被依赖的Bean需要表示成RuntimeBeanReferenc对象,并将它放到BeanDefinition的MutablePropertyValues中。
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
AbstractAutowireCapableBeanFactory#initializeBean
AbstractAutowireCapableBeanFactory
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
}
DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
}
ConfigurableListableBeanFactory
提供bean definition的解析,注册功能,对单例Bean预加载(解决循环依赖问题).
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
/**
* 忽略类型
*/
void ignoreDependencyType(Class<?> type);
/**
* 忽略接口
*/
void ignoreDependencyInterface(Class<?> ifc);
void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
/**
* 获取bean定义 (可以访问属性值跟构造方法的参数值)
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
Iterator<String> getBeanNamesIterator();
void clearMetadataCache();
/**
* 锁定配置信息.在调用refresh时会使用到.
*/
void freezeConfiguration();
/**
* 锁定配置信息.在调用refresh时会使用到.
*/
boolean isConfigurationFrozen();
/**
* 预加载不是懒加载的单例.用于解决循环依赖问题
*/
void preInstantiateSingletons() throws BeansException;
}
AutowireCapableBeanFactory
AutowireCapableBeanFactory在BeanFactory基础上实现了对存在实例的管理.可以使用这个接口集成其它框架,捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用.
一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,如果真手痒痒可以通过ApplicationContext的getAutowireCapableBeanFactory接口获取.
AutowireCapableBeanFactory源码 具体:
-
总共5个静态不可变常量来指明装配策略,其中一个常量被Spring3.0废弃、一个常量表示没有自动装配,另外3个常量指明不同的装配策略——根据名称、根据类型、根据构造方法。
-
8个跟自动装配有关的方法,实在是繁杂,具体的意义我们研究类的时候再分辨吧。
-
2个执行BeanPostProcessors的方法。
-
2个分解指定依赖的方法
总结:这个工厂接口继承自BeanFacotory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器等。
public interface AutowireCapableBeanFactory extends BeanFactory {
// code
}
ListableBeanFactory
获取bean时,Spring 鼓励使用这个接口定义的api. 还有个Beanfactory方便使用.其他的4个接口都是不鼓励使用的.
提供容器中bean迭代的功能,不再需要一个个bean地查找.比如可以一次获取全部的bean(太暴力了),根据类型获取bean.在看SpringMVC时,扫描包路径下的具体实现策略就是使用的这种方式(那边使用的是BeanFactoryUtils封装的api).
如果同时实现了HierarchicalBeanFactory,返回值不会考虑父类BeanFactory,只考虑当前factory定义的类.当然也可以使用BeanFactoryUtils辅助类来查找祖先工厂中的类.
这个接口中的方法只会考虑本factory定义的bean.这些方法会忽略ConfigurableBeanFactory的registerSingleton注册的单例bean(getBeanNamesOfType和getBeansOfType是例外,一样会考虑手动注册的单例).当然BeanFactory的getBean一样可以透明访问这些特殊bean.当然在典型情况下,所有的bean都是由external bean定义,所以应用不需要顾虑这些差别.
注意:getBeanDefinitionCount和containsBeanDefinition的实现方法因为效率比较低,还是少用为好.
public interface ListableBeanFactory extends BeanFactory {
//是否包含bean
boolean containsBeanDefinition(String beanName);
// 当前factory中定义的bean数量
int getBeanDefinitionCount();
// 获取当前工厂中定义的所有bean 的name
String[] getBeanDefinitionNames();
//这边的方法仅检查顶级bean.它不会检查嵌套的bean.FactoryBean创建的bean会匹配为FactoryBean而不是原始类型.
//一样不会考虑父factory中的bean,非要用可以通过BeanFactoryUtils中的beanNamesForTypeIncludingAncestors.
//其他方式注册的单例这边会纳入判断.这个版本的getBeanNamesForType会匹配所有类型的bean,包括单例,原型,FactoryBean.返回的bean names会根据backend 配置的进行排序.
// 获取给定类型的bean names(包括子类),通过bean 定义或者FactoryBean的getObjectType判断.
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(Class<?> type);
// 如果保护懒加载的类,FactoryBean初始化的类和工厂方法初始化的类会被初始化.就是说执行这个方法会执行对应的初始化.
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
//查找使用注解的类
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
// 查找一个类上的注解,如果找不到,父类,接口使用注解也算.
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
}
StaticListableBeanFactory
public class StaticListableBeanFactory implements ListableBeanFactory {
}
AutowireCapableBeanFactory
在BeanFactory基础上实现对已存在实例的管理.
可以使用这个接口集成其它框架,捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用.
一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,如果真手痒痒可以通过ApplicationContext的getAutowireCapableBeanFactory接口获取.
这边定义了5种自动装配策略:不注入AUTOWIRE_NO,使用bean name策略装配AUTOWIRE_BY_NAME,使用类型装配策略AUTOWIRE_BY_TYPE,使用构造器装配策略AUTOWIRE_CONSTRUCTOR,自动装配策略AUTOWIRE_AUTODETECT
这边的自动策略是先尝试构造器,然后才是byType.这边应该是跟xml配置文件中的装配策略对应.
public interface AutowireCapableBeanFactory extends BeanFactory {
<T> T createBean(Class<T> beanClass) throws BeansException;
void autowireBean(Object existingBean) throws BeansException;
Object configureBean(Object existingBean, String beanName) throws BeansException;
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
Object initializeBean(Object existingBean, String beanName) throws BeansException;
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
void destroyBean(Object existingBean);
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}
SingletonBeanRegistry
这边定义的单例注册,主要就是相对BeanFactory的api而言有点low,没有做附加的处理.
- 注册的时候不管注入afterPropertiesSet的初始化回调.
- 查找的时候不管还没初始化的单例不说,还不管别名问题,不管FactoryBean如何区分是获取FactoryBean本身还是getObject初始化的实例.
public interface SingletonBeanRegistry {
/**
* 这边的实现不会再调用初始化回调函数,如InitializingBean 的afterPropertiesSet,
* 所以这边应该接收的是完成初始化的实例同理也不会调用销毁的回调,如DisposableBean的destroy
* 这跟标准的BeanFactory中注册单例是明显不同的,因为那边是会调用各种回调.
*/
void registerSingleton(String beanName, Object singletonObject);
/**
* 手动注册的单例.
* 只会查找已经初始化完毕的单例,有bean definition但没有实例化的这边查找不到.
* 也不会处理FactoryBean的情况(就是具体获取getObject还是factoryBean本身的区分,&),别名也需要预先转化好了来查.
*/
Object getSingleton(String beanName);
/**
* 只有单例已经实例化才会返回true,剩下的看3.2查找单例的说明吧,一样的.
*/
boolean containsSingleton(String beanName);
String[] getSingletonNames();
int getSingletonCount();
Object getSingletonMutex();
}
DefaultSingletonBeanRegistry
实现单例与DisposableBean的生命周期管理(创建,维护,销毁),在SingletonBeanRegistry注册的基础上,添加单例的共享,支持容器关闭时,DisposableBean实例的销毁
- bean的注册
这边注册时,通过下面四个变量来维护:
Map<String, Object> singletonObjects 缓存以bean name为key的单例实例
Map<String, ObjectFactory> singletonFactories 缓存以bean name 为key的ObjectFactory
Map<String, Object> earlySingletonObjects 用于解决单例时的循环依赖,这边缓存以bean name为key的预初始化单例
Set registeredSingletons 已经注册好的单例bean name
这边singletonObjects和registeredSingletons的数据应该是同步的,只是适用于不同的场景,但他们俩跟singletonFactories 和earlySingletonObjects分别互斥,就是singletonObjects里有了,这两个肯定没有.
同时这边也有inCreationCheckExclusions和singletonsCurrentlyInCreation进行锁控制的概念。ngletonsCurrentlyInCreation缓存bean正在被初始化,这样就不能再发起初始化;inCreationCheckExclusions直接缓存当前不能加载的bean
这部分看个例子就,清晰了,初始化前需要先使用beforeSingletonCreation判断,这边inCreationCheckExclusions不包含beanName才会去判断singletonsCurrentlyInCreation
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.containsKey(beanName) &&
this.singletonsCurrentlyInCreation.put(beanName, Boolean.TRUE) != null) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
- 管理bean的依赖问题
使用如下三个属性进行管理:
Map<String, Set> containedBeanMap 依赖的bean name为key , 就是依赖类 -> 查找 被依赖的类
Map<String, Set> dependentBeanMap 依赖的原始bean name为key
Map<String, Set> dependenciesForBeanMap 被依赖的bean name为key
- bean 销毁
这不过跟初始化类似,自行看代码比较简单.
FactoryBeanRegistrySupport
添加对FactoryBean的支持,就是使用工厂方法初始化类.
这里主要涉及3个新概念:FactoryBean,BeanPostProcessor和AccessController.这三个概念懂了,源码也就分析完了.
-
FactoryBean,通过T getObject() api提供简单工厂方法,可用用于创建单例,原型模式的实例.主要用于创建过程复杂,xml配置不方便的情况。其实这个就是使用spring的接口对简单工厂设计模式做了一个规范,方便大家在spring中配置使用.
-
BeanPostProcessor用于bean 初始化时进行功能增强,类似web开发中的filter.
-
AccessController jdk的安全控制
在 Java 中将执行程序分成本地和远程两种,本地代码默认视为可信任的,而远程代码则被看作是不受信的。对于授信的本地代码,可以访问一切本地资源。
在应用开发中还有一些关于安全的复杂用法,其中最常用到的 API 就是 doPrivileged。doPrivileged 方法能够使一段受信任代码获得更大的权限,甚至比调用它的应用程序还要多,可做到临时访问更多的资源。
所以就出现了spring中的典型代码
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}else {
object = factory.getObject();
}
AliasRegistry
定义bean name的别名管理
public interface AliasRegistry {
//注册别名
void registerAlias(String name, String alias);
//移除别名
void removeAlias(String alias);
//校验别名
boolean isAlias(String name);
//获取别名
String[] getAliases(String name);
}
SimpleAliasRegistry
除了实现接口定义的api,还添加了两个公共api:
- 批量校验别名public void resolveAliases(StringValueResolver valueResolver)
- 查找别名对应的原始类名public String canonicalName(String name)
bean在实例化之前,必须是在bean容器启动之后。所以就有了两个阶段:
-
bean容器的启动阶段;
-
容器中bean的实例化阶段;
bean容器的启动阶段
BeanDefinition
- 首先是读取bean的xml配置文件,然后解析xml文件中的各种bean的定义,将xml文件中的每一个元素分别转换成一个
BeanDefinition
对象,其中保存了从配置文件中读取到的该bean的各种信息:
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
private volatile Object beanClass;
private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false;
private boolean lazyInit = false;
private int autowireMode = AUTOWIRE_NO;
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
private String[] dependsOn;private ConstructorArgumentValues constructorArgumentValues;
private MutablePropertyValues propertyValues;private String factoryBeanName;
private String factoryMethodName;
private String initMethodName;
private String destroyMethodName;
- beanClass保存bean的class属性,
- scop保存bean是否单例,
- abstractFlag保存该bean是否抽象,
- lazyInit保存是否延迟初始化,
- autowireMode保存是否自动装配,
- dependencyCheck保存是否坚持依赖,
- dependsOn保存该bean依赖于哪些bean(这些bean必须提取初始化),
- constructorArgumentValues保存通过构造函数注入的依赖,
- propertyValues保存通过setter方法注入的依赖,
- factoryBeanName和factoryMethodName用于factorybean,也就是工厂类型的bean,
- initMethodName和destroyMethodName分别对应bean的init-method和destory-method属性,比如:
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<bean>
元素可以配置的属性:
除了 id 和 class 属性之外,还有一些可选的属性:
-
scope属性,默认 的 scope就是 singleton=“true”, springmvc和struts2的重要区别之一就是spring的controll是单例的,而struts2的action是:scope=“prototype” ,还有 scope=“request” , scope=“session”,scope=“globalSession”(仅用于portlet)
-
abstract属性,是否是抽象的bean:
<bean id="baseDAO" abstract="true">
<property name="dataSource" ref="dataSource" />
<property name="sqlMapClient" ref="sqlMapClient" />
</bean>
<bean id="collectionDAO" class="net.minisns.dal.dao.CollectionDAOImpl" parent="baseDAO" />
<bean id="commentDAO" class="net.minisns.dal.dao.CommentDAOImpl" parent="baseDAO" />
-
depends-on 依赖于某个bean,其必须先初始化:
-
lazy-init=“true” 是否延迟初始化,默认为 false
-
dependency-check 是否对bean依赖的其它bean进行检查,默认值为 none,可取值有:none, simple, object, all等
-
factory-method 和 factory-bean用于静态工厂和非静态工厂:
<bean id="bar" class="...StaticBarInterfaceFactory" factory-method="getInstance"/>
<bean id="barFactory" class="...NonStaticBarInterfaceFactory"/>
<bean id="bar" factory-bean="barFactory" factory-method="getInstance"/>
-
init-method, destory-method 指定bean初始化和死亡时调用的方法,常用于 dataSource的连接池的配置
-
lookup-method 方法注入:
<bean id="newsBean" class="..xxx" singleton="false">
<bean id="mockPersister" class="..impl.MockNewsPersister">
<lookup-method name="getNewsBean" bean="newsBean"/>
</bean>
表示 mockPersister 有一个依赖属性 newsBean,该属性的每次注入都是通过调用newsBean.getNewsBean() 方法获得的。
- autowire 是否启用自动装配依赖,默认为 no, 其它取值还有:byName, byType, constructor
BeanDefinitionRegistry
- 读完配置文件之后,得到了很多的
BeanDefinition
对象,然后通过BeanDefinitionRegistry
将这些bean注册到beanFactory中:
public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String beanName);
}
BeanFactory
的实现类,需要实现BeanDefinitionRegistry
接口:
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// ... ...
this.beanDefinitionMap.put(beanName, beanDefinition);
// ... ...
}
我们看到BeanDefinition
被注册到了 DefaultListableBeanFactory
, 保存在它的一个ConcurrentHashMap
中。
BeanFactoryPostProcessor
将BeanDefinition注册到了beanFactory之后,在这里Spring为我们提供了一个扩展的切口,允许我们通过实现接口BeanFactoryPostProcessor 在此处来插入我们定义的代码:
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
典型的例子就是:PropertyPlaceholderConfigurer
,我们一般在配置数据库的dataSource时使用到的占位符的值,就是它注入进去的:
public abstract class PropertyResourceConfigurer extends PropertiesLoaderSupport
implements BeanFactoryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
Properties mergedProps = mergeProperties();
// Convert the merged properties, if necessary.
convertProperties(mergedProps);
// Let the subclass process the properties.
processProperties(beanFactory, mergedProps);
}
catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
processProperties(beanFactory, mergedProps)
在子类中实现的,功能就是将${jdbc_username}等等这些替换成实际值。
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc_url}" />
<property name="username" value="${jdbc_username}" />
<property name="password" value="${jdbc_password}" />
</bean>
容器中bean的实例化阶段
实例化阶段主要是通过反射或者CGLIB对bean进行实例化,在这个阶段Spring又给我们暴露了很多的扩展点。
Aware
各种的Aware接口,比如 BeanFactoryAware,MessageSourceAware,ApplicationContextAware
对于实现了这些Aware接口的bean,在实例化bean时Spring会帮我们注入对应的:BeanFactory, MessageSource,ApplicationContext的实例:
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
public interface MessageSourceAware extends Aware {
void setMessageSource(MessageSource messageSource);
}
BeanPostProcessor
实现了BeanPostProcessor接口的bean,在实例化bean时Spring会帮我们调用接口中的方法:
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
从注释中可以知道 postProcessBeforeInitialization方法在 InitializingBean接口的 afterPropertiesSet方法之前执行,而postProcessAfterInitialization方法在 InitializingBean接口的afterPropertiesSet方法之后执行。
InitializingBean
实现了InitializingBean接口的bean,在实例化bean时Spring会帮我们调用接口中的方法:
public interface InitializingBean {
/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception;
}
DisposableBean
实现了BeanPostProcessor接口的bean,在该bean死亡时Spring会帮我们调用接口中的方法:
public interface DisposableBean {
/**
* Invoked by a BeanFactory on destruction of a singleton.
* @throws Exception in case of shutdown errors.
* Exceptions will get logged but not rethrown to allow
* other beans to release their resources too.
*/
void destroy() throws Exception;
}
InitializingBean
接口和DisposableBean
接口对应于 的 init-method 和 destory-method 属性,其经典的例子就是dataSource:
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
所以在Spring初始化 dataSource 这个bean之后会调用 DruidDataSource.init 方法,基本就是初始化数据库连接池。
在dataSource 这个bean死亡时会调用 DruidDataSource.close()方法,基本就是关闭连接池中的连接。
另外注解 @PostConstruct 和 @PreDestroy 也能达到 InitializingBean接口 和 DisposableBean接口的效果。
总结
spring容器接管了bean的实例化,不仅仅是通过依赖注入达到了松耦合的效果,同时给我们提供了各种的扩展接口,来在bean的生命周期的各个时期插入我们自己的代码:
-
BeanFactoryPostProcessor接口(在容器启动阶段)
-
各种的Aware接口
-
BeanPostProcessor接口
-
InitializingBean接口(@PostConstruct, init-method)
-
DisposableBean接口(@PreDestroy, destory-method)
FactoryBean
实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getOjbect()方法的返回值:
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
典型的例子有spring与mybatis的结合:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:config/mybatis-config-master.xml" />
<property name="mapperLocations" value="classpath*:config/mappers/master/**/*.xml" />
</bean>
我们看上面该bean,因为实现了FactoryBean接口,所以返回的不是 SqlSessionFactoryBean 的实例,而是她的 SqlSessionFactoryBean.getObject() 的返回值:
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
private static final Log logger = LogFactory.getLog(SqlSessionFactoryBean.class);
private Resource configLocation;
private Resource[] mapperLocations;
private DataSource dataSource;
private SqlSessionFactory sqlSessionFactory;
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}
return this.sqlSessionFactory;
}
其实他是一个专门生产 sqlSessionFactory 的工厂,所以才叫 SqlSessionFactoryBean。 而SqlSessionFactory又是生产SqlSession的工厂。
还有spring与ibatis的结合:
<!-- Spring提供的iBatis的SqlMap配置 -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sqlmap/sqlmap-config.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>, InitializingBean {
private Resource[] configLocations;
private Resource[] mappingLocations;
private Properties sqlMapClientProperties;
private DataSource dataSource;
private boolean useTransactionAwareDataSource = true;
private Class transactionConfigClass = ExternalTransactionConfig.class;
private Properties transactionConfigProperties;
private LobHandler lobHandler;
private SqlMapClient sqlMapClient;
public SqlMapClient getObject() {
return this.sqlMapClient;
}
SqlMapClientFactoryBean 返回的是 getObject() 中返回的 sqlMapClient, 而不是 SqlMapClientFactoryBean 自己的实例。
依赖注入(DI)
构造函数注入
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" ref="bar"/>
</bean>
<bean id="bar" class="x.y.Bar"/>
构造函数注入使用:<constructor-arg index="0" value="7500000"/>
, <constructor-arg type="int" value="7500000"/>
,对于非简单参数,需要使用ref <constructor-arg index="1" ref="bar"/>
setter方法注入
setter方法注入使用 <property name="username" value="xxx"/>
, 非简单类型属性使用ref <property name="xxbean" ref="xxx"/>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:config/mybatis-config.xml" />
<property name="mapperLocations" value="classpath*:config/mappers/**/*.xml" />
</bean>
集合等复杂类型的注入:
<bean id="moreComplexObject" class="example.ComplexObject">
<!-- results in a setAdminEmails(java.util.Properties) call -->
<property name="adminEmails">
<props>
<prop key="administrator">administrator@example.org</prop>
<prop key="support">support@example.org</prop>
<prop key="development">development@example.org</prop>
</props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
<list>
<value>a list element followed by a reference</value>
<ref bean="myDataSource" />
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
<map>
<entry key="an entry" value="just some string"/>
<entry key ="a ref" value-ref="myDataSource"/>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="myDataSource" />
</set>
</property>
</bean>
也很简单,list属性就是 <list>
里面包含<value>
或者<ref>
或者<bean>
, set也类似。map是<map>
里面包含<entry>
这个也好理解,因为map的实现就是使用内部类Entry来存储key和value. Properties是<props>
里面包含<prop>
。