为了更加熟悉spring的总体流程,看了spring的源码。
看了很多网上的资料写的spring的bean的生命周期,但是感觉和看到的源码有部分出入,这里再总结下。
正文:
spring获取bean的时候有两种方式:
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
Object t = bf.getBean("myBean");
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Object t = ac.getBean("myBean");
这篇文章先看第一种方式,使用beanFactory加载bean并获取
new ClassPathResource("applicationContext.xml") 这句话是加载资源文件的,主要是把配置文件映射到spring的配置文件对象Resource中,逻辑比较多,这里我们不关注,有兴趣的同学可以自行学习
当获取到resource后我们进入加载XmlBeanFactory的逻辑,我们只关注主线,如何获取bean(即getBean("mybean")方法)。跟踪代码,我们发现了这样的继承关系:
XmlBeanFactory <-- DefaultListableBeanFactory <--AbstractAutowireCapbleBeanFactory <-- AbstractBeanFactory
在 AbstractBeanFactory中我们找到了getBean(“”)的方法调用。下边是代码,我写了些注释帮助理解
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
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;
// Eagerly check singleton cache for manually registered singletons.
/**
* 检查缓存中或者实例工厂中是否有对应的bean
* 为什么首先会使用这段代码呢?
* 因为在创建单例bean的时候会存在依赖注入的情况,而创建依赖的时候为了避免循环依赖
* Spring创建bean的原则是不等bean创建完成就将创建bean的ObjectFactory提早曝光
* 也就是将ObjectFactory加入缓存,一旦下一个bean创建的时候需要依赖上一个bean的时候直接使用objectFactory
*
*/
//直接尝试从缓存中获取,或者singletonfacotory中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
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 + "'");
}
}
//返回对应的实例,有时候存在诸如beanFactory的情况并不是直接返回实例本身,而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//只有在单例情况才会尝试解决循环依赖。原型模式下如果存在A中有b,b中有A,
//那么当依赖注入的时候就会产生当A还未创建完的时候对于B的创建再次返回创建A
//造成循环依赖 也就是下面的情况
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果beanDefinitionMap中也就是已经加载的bean类中不包括beanName,则尝试从parentbeanfactory中获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
//递归到parentFacotory中寻找
// 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);
}
}
//如果不是仅仅做类型检查而是创建bean这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//将存储XML配置文件的GericBeanDefinition转换为RootBeanDefinition,如果指定Beanname是子类的话会同时合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
//若存在依赖则要递归实例化依赖的bean
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
getBean(dependsOnBean);
//缓存依赖调用
registerDependentBean(dependsOnBean, beanName);
}
}
// Create bean instance.
//实例化依赖的bean后就可以实例化mdb本身了
//singleton模式的创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
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.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//prototype的创建(new)
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);
}
//指定scope上的实例化
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
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);
}
}
}
//检查需要的类型是否符合bean的实际类型
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
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;
}
上面的逻辑比较多,其实有这么几个事情大家需要知道的(我们先重点关注singleaton策略,原生的不关注)。
- spring在生成bean的时候其实是先生成一个创建bean的工厂,一般情况(即普通类)是一个ObjectFactory的工厂类来生成bean。
- 生成的这个factoryBean在生成之后并没有完事,还需要把这个工厂放到缓存中以备后续其他的bean用的这个bean的时候直接调用工厂获取bean,其实工厂生成的bean也已经存到缓存中,当其他bean需要这个bean的时候直接调用工厂生成bean,如果已经生成了,工厂会直接从缓存中拿出这个bean。(很多同学想不通为什么spring要搞个工厂来生成bean,直接存bean不就好了,其实是因为spring需要解决bean质检的循环依赖才引入的,A->B->C->A 感兴趣的同学可以自行研究,这里我们跳过,只关注主线逻辑。
通篇看一遍上面的代码,给bean赋值的只有这个方法了,我们进去看看
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
//如果指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型验证不通过
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
//现在我们有个bean的实例,这个实例可能是bean或者是beanFactory的实例
//如果是FacotryBean我们使用它创建bean,但是如果用户想要获取工厂实例而不是工厂的getObject方法对应的实例那么传入的name应该加入前缀&
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//加载FactoryBean
Object object = null;
if (mbd == null) {
//尝试从缓存中加载bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
//这一已经知道实例一定是beanFactory类型的
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
//将存储xml配置的GenricBeanDefinition转换为rootbeanDefinition,如果指定beanName是子类的话同时会合并父类的相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是用户定义的不是应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
上面的代码我们又这么几个事情需要知道
- 初始化一个bean我们有三种方案 (1)简单初始化(就是什么都不管,直接调用bean的空创建方法进行初始化)(2)带参初始化(就是我们需要在spring配置文件中指定参数,我想大家都应该见过)(3)自定义工厂方式初始化
- 针对上面的自定义工厂方式我估计很多同学没有怎么用过,多说一些,平常我们在spring中会这样定义一个bean
<bean id="testListener" class="test.beans.TestListener"></bean>
其实我们还可以定义一个FacotryBean来控制生成的bean,前提是我们的bean需要实现FactoryBean<T>接口,像这样
public class TestFactoryBean implements FactoryBean<Test>{
public Test getObject() throws Exception {
return new Test();
}
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return null;
}
public boolean isSingleton() {
// TODO Auto-generated method stub
return false;
}
}
然后我们在配置文件里只需要修改bean定义的class为我们新建的factory就可以了
<bean id="testListener" class="test.beans.TestFactoryBean"></bean>
上面的如果采用了自定义方式的factory类生成bean,其实我们可以通过在类名前加“&”符号的方式来获取他,像这样
TestFacotryBean ttb = (TestFactoryBean)getBean("&testListener")
-------------------------------------------------------------------------------------------------------------------------
好我们接着看下面的逻辑,这个方法里我们发现先是从缓存中获取bean,没有的话再往下走,我们分析的是第一次加载,肯定是要往下走了,分析这个方法
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
return (object != NULL_OBJECT ? object : null);
}
}
else {
return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
}
}
在上面的方法中所有的bean赋值都指向了这个方法,接着跟进
doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(
final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
throws BeanCreationException {
Object object;
try {
//需要权限验证
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 {
//直接调动getObject方法
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
if (object != null && shouldPostProcess) {
try {
//调用objectFactory的后处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
}
}
return object;
}
上面的方法里我们看到最核心的一句话
//直接调动getObject方法
object = factory.getObject();
这里我们才知道,原来获取bean获取到最后我们还是需要从我们开始定义的FactoryBean中才能找到答案,就和我刚开始解释的一样,spring所有的bean生成都委托给我factoryBean类。这也是为什么我在上面要专门讲一下自定义生成bean的方式了,这样才能帮助理解。
--------------------------------------------------------------------------------------------------------------
好了,我们接着看看factoryBean中到底搞了什么事情,依次反查这个方法的调用,找到factoryBean最开始设置的地方,我们找到了这里
// Create bean instance.
//实例化依赖的bean后就可以实例化mdb本身了
//singleton模式的创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
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.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
定位到createBean方法
@Override
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
// Make sure bean class is actually resolved at this point.
//锁定class,根据设置的class属性或者根据classname来解析class
resolveBeanClass(mbd, beanName);
// Prepare method overrides.
//验证及准备覆盖的方法
try {
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//给BeanPostProcessors一个机会来返回一个代理类类来替换真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
上面的方法中有个很重要的地方我必须要说一下,虽然和我们的主线没什么关系就是这句话。
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//给BeanPostProcessors一个机会来返回一个代理类类来替换真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
在这个函数下面调用doCreateBean之前,调用了个resolveBeforeInstantiation方法,还返回了个bean,并且这个bean不为空的话直接返回,后面的逻辑都不走了,大家可以想想原因。这就是著名的AOP实现的地方,这里是非常重要的代码,resolveBeforeInstantiation中通过AOP制定的代理类生成一个新的bean,这里监控到bean被改变了就直接返回新的代理类了。
好,闲话不多说,接着走发现了这个方法
Object beanInstance = doCreateBean(beanName, mbd, args);
其实Spring的代码核心的都是doxxxxxx(),其他的都是组织代码结构的。进去看看。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入,简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
//利用MergedBeanDefinitionPostProcessors
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//是否需要提早曝光:单例&允许循环依赖&当前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");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
//对bean再一次依赖引用,主要应用SmartInstatiantionAware BeanPostProccessor
//其中我们熟悉的AOP就是在这里将advice动态织入的,若没有则直接返回bean不做任何处理
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//调用初始化方法,比如init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
//earlySingletonReference 只有检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
//如果exposedObject没有被改变也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/**
* 因为bean创建后,其依赖的bean一定是已经创建的
* actualDependentBeans不为空标识当前bean创建后其依赖的bean却没有创建完成。也就是说存在循环依赖
*/
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 {
//根据scope注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
上面看的有点多,我们需要知道的有这几个
- spring在加载完配置文件后会把这个bean的定义放到佳作RootBeanDefinition的类中保存起来,之后方法调用传参也用这个类,包括属性的保存等等
- 然后通过RootBeanDefinition生成了一个beanWrapper的类,这个类中包含了我们的bean,和bean的属性的描述信息
- 而我们需要的其实只是beanWrapper中的bean
好了,这次思路比较清晰,先生成一个beanWrapper,然后获取其中的bean就好了
看第一个生成beanWrapper的方法
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入,简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
进去
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
//解析class
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());
}
//如果工厂方法不为空则使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
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);
}
}
// Need to determine the constructor...
//需要根据参数解析构造函数
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);
}
上面的代码看看结构,大概分为三个逻辑
- 有工厂方法的用工厂方法初始化(同学们不要看错了,这里是工厂方法,不是工厂类,spring中可以通过factory-method标签指定生成当前类的方法的)
- 有参数的用参数初始化(这里有个构造方法缓存的问题,我们不讨论)
- 没有参数的调用默认的构造函数初始化
接着跟进只看默认构造函数
//使用默认的构造函数
return instantiateBean(beanName, mbd);
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
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;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
看到这句话,接着跟进
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (beanDefinition.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (beanDefinition.constructorArgumentLock) {
constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class clazz = beanDefinition.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
public Constructor run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(beanDefinition, beanName, owner);
}
}
这里大家也许很疑惑为什么跑出一个
if (beanDefinition.getMethodOverrides().isEmpty()) {
其实我们在定义bean的时候有个功能很少用到,就是replace-method 和 lookup-method方法,我们在配置文件中用了这两个方法后就能直接替换原始bean的任何一个方法的实现,但前提是我们要使用cglib,因为这里需要使用动态代理替换实现类为代理类
上面的方法终于看到了我们需要的代码,从这个方法进去就能看到通过构造方法生成类的方法了,关注下当前到了哪个类里了,是个叫做SimpleInstantiationStragety的类,这个类是实现了InstantiationStrategy类,也是唯一的实现类。这说明所有的简单初始化操作我们都是走的这个类。
return BeanUtils.instantiateClass(constructorToUse);
兄弟们不要着急,到现在为止我们只是创建了一个bean,里边的属性还都没设置呢,回到之前的doCreateBean方法,
try {
//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//调用初始化方法,比如init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
上面的属性注入过程我们进去看看
protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
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.
//给instantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变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);
// 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;
}
//后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//需要减产依赖
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
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) {
//回来检查 对应depends-on属性,3.0已经弃用此属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
上面的逻辑主要分为这几项
- 通过后处理器来控制属性是否继续填充(这里我们先不关注)
- 通过byType或者byName的方式获取属性值
- 将属性值应用到beanWrapper中
重点在这里
if (exposedObject != null) {
//调用初始化方法,比如init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
看看这个方法里面做了什么
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
//对特殊的bean处理:aware、BeanClassLoaderAware,beanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//应用后处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//激活用户自定义的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//后处理器应用
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
上面的代码主要分为三块逻辑,设置beanWare,初始化bean,调用后处理器的处理方法。
我们需要知道这么几个事情
- 一般情况下其实我们不需要关注我们的bean生成过程中到底用了什么类加载器,用的是哪个工厂做的操作(如果不是我们自定义的话),如果想要知道该怎么办呢?spring给我留了方法,就是让bean去实现ware接口,需要name的话实现BeanNameAware,需要类加载器则实现BeanClassLoaderAware,需要bean工厂,则实现BeanFactoryAware,所以这里有一步是设置相应ware需要的对应资源的。
- spring在控制bean生成的时候留了很多扩展功能接口,后处理器(beanPostProcessor)就是其中之一,如果我们想要在bean生成的前后做一些事情,比如打日志,写入新的属性之类的,都可以通过beanPostProcessor来设置。但是我们貌似通篇也没有看到到底在哪里设置了beanPostProcessor。其实通过beanFacotry方式获取bean的时候spring把添加后处理器的方法交给了我们。我们可以这样做:
DefaultListableBeanFactory bf = new XmlBeanFactory(new ClassPathResource(""));
bf.addBeanPostProcessor(beanPostProcessor);
这样就添加了一个beanPostPorcessor
恩,上面还有一个逻辑是初始化逻辑,就是调用配置文件中配置的init-method方法,我们梳理下整个逻辑
- 如果bean实现了aware方法,则先处理aware方法的实现方法
- 如果存在后处理器,则调用后处理器的postProcessBeforInitialization方法
- 调用bean的init-method方法
- 如果存在后处理器,则调用后处理器的postProcessAfterInitialization方法
后面还有一点逻辑,就是下面这段代码
try {
//根据scope注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
进去看看
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()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
/**
* 单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean
*/
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
这里是注册销毁bean的逻辑,这里涉及到spring的后置处理器,beanPostProcessor的东西,暂时不考虑,总之就是要销毁这个bean,并销毁他所占用的缓存等资源(像之前说的beanFactory缓存,bean缓存等等)
现在我们再说说原型模式的获取方式,在我们刚开始的函数doGetBean方法中,有这样的方法
//singleton模式的创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
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.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//prototype的创建(new)
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);
}
对比看看这个if else。if里的逻辑是单例singleaton,else里是prototype原型。
发现了:其实单例方式只是比原型方式多了一个objectFacotry。也就是说,单例必须先弄个objectFactory,然后再通过objectFacotry去生成bean才行;而原型模式直接createBean();就能创建,后边的逻辑一样,到了abstractAutoWireCapableBeanFactory中的doCreateBean();方法,利用SimpleInstantiationStragety创建bean,然后注入属性,然后注册销毁,然后返回。
---------------------------------------------------------------------------------------------------------------------------------
总结下:
我们到目前为止说的都是通过beanFacotry生成bean的逻辑,也就是两种方式中的一种(另外一种是xmlApplicationContext)。
看到其他一些资料里说spring的bean生成核心类是DefaultListableBeanFacotry,其实我感觉更像是AbstractAutowireCapableBeanFactory,因为核心的doCreate()方法是在这里实现的。里面交代了bean会在这里利用SimpleInstantiationStragety类进行简单初始化,并在doCreateBean方法中完成对属性的注入,到这里完成了所有beanWrapper类的装配,然后又获取beanWrapper中的bean类型,对bean添加了aware和postProcess的处理逻辑,然后又在这里完成了对bean销毁方式的注册。然后层层返回之后就是getBean(“myBean”)得到的结果了。
总结步骤:
- 利用SimpleInstantiationStragety进行初始化(可以是工厂方式的,也可以是单参数形式的,也可以是无参数的简单初始化),结果是我们得到了一个实例,但是属性都是空的
- 进行属性的注入,这里分别通过byName或者byType获取属性信息,并递归调用getBean方法获取属性bean
- 根据bean实现的aware接口调用相应的aware方法设置资源(beanNameAware,BeanClassLoaderAware,BeanFactoryAware)
- 如果实现了后处理器BeanPostProcessor,则遍历后处理器调用postProcessBeforeInitialization方法处理逻辑
- 调用用户自定义的init-method方法
- 如果实现了InitializingBean接口则调用afterPropertiesSet方法,这个方法只会在所有属性都被设置的时候才会触发
- 如果实现了后处理器BeanPostProcessor,则遍历后处理器调用postProcessAfterInitialization方法处理逻辑
- bean可以使用了