上一篇中对IOC容器的主要功能进行了分析,比如Bean的载入以及解析,依赖注入的实现等,这一篇中会对容器的其他相关特性也进行分析,这些特性都是我们在使用容器是会经常遇到的。
一.Bean的生命周期
首先简单介绍一下bean的生命周期
1.bean实例的创建
2.为bean的实例注入属性
3.调用Bean的初始化方法
4.应用可以通过IOC容器使用bean
5.容器关闭时,调用bean的销毁方法
Bean实例的创建以及注入的过程在上一篇已经分析过,我们主要来看看Bean的初始化方法的调用过程,这个过程是在AbstractCapableBeanFactory的initializeBean方法中实现的,方法代码如下:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
//执行bean的一系列Aware方法(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>(){
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//如果bean实现了BeanPostProcessor,执行postProcessBeforeInitialization方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//如果bean实现了InitializingBean接口,调用它的afterPropertiesSet方法,然后调用Bean的init-Mehthod方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//如果bean实现了BeanPostProcessor,执行postProcessAfterInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
然后我们再来看一看Bean的销毁的过程, 当我们需要关闭容器时,可以通过容器的destroy方法或close方法来销毁容器,销毁容器的过程的具体的实现是在AbstractApplicationContext的doClose方法中,方法方法代码如下:
protected void doClose() {
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// 发布容器关闭事件
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
//销毁bean
destroyBeans();
// 关闭容器
closeBeanFactory();
// 这个方法留给子类实现,子类可以定制销毁容器时的一些操作
onClose();
this.active.set(false);
}
}
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
public void destroySingletons() {
super.destroySingletons();
this.manualSingletonNames.clear();
clearByTypeCache();
}
public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
//遍历销毁所有需要销毁的bean
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
//清空相关的缓存
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
}
销毁bean的具体实现在destroySingleton方法中
public void destroySingleton(String beanName) {
//清除当前bean的相关的缓存
removeSingleton(beanName);
//销毁bean,这里的disposableBean是一个DisposableBeanAdapter的实例
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}
protected void destroyBean(String beanName, DisposableBean bean) {
//递归的销毁所有的依赖bean
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
//这个bean是一个DisposableBeanAdapter的实例,执行对bean的销毁处理
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
//递归的销毁当前所包含的内部的bean
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
// 移除其他依赖当前bean的依赖关系
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
}
下面看看DisposableBeanAdapter中的destroy方法的实现
public void destroy() {
//首先对postProcessBeforeDestruction进行调用
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
//如果实现了DisposableBean接口,调用bean的destroy方法
if (this.invokeDisposableBean) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((DisposableBean) bean).destroy();
return null;
}
}, acc);
}
else {
((DisposableBean) bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
//调用用户自定义的destroy-method方法
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod();
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
整个bean的生命周期的分析到这里就结束了
二、Bean的lazy-init属性
在上一篇Spring源码解析(一):Spring的IOC实现中分析依赖注入的过程时说过,如果bean为singleton并且未配置lazy-init属性(默认为false),那么会在初始化容器时,在解析载入BeanDefinition时会触发Bean的预实例化,这个过程会触发bean的依赖注入,否则就在用户第一次调用getBean向IOC容器索要bean时触发。下面来看一看这个过程是如何实现的,首先来看看AbstractApplicationContext中的refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
//这里是对lazy-init属性进行处理的地方
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
//这个方法中有对lazy-init属性的相关处理,方法的具体实现在DefaultListableBeanFactory中
beanFactory.preInstantiateSingletons();
}
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
//遍历所有的beanName
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//注入所有的单例的并且未配置lazy-init属性或lazy-init属性为false的bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
三、FactoryBean的实现
FactoryBean是一种特殊的Bean,它是一个可以产生或者修饰对象的工厂Bean,与设计模式中的工厂模式以及装饰器模式类似。通过实现org.springframework.beans.factory.FactoryBean来创建一个FactoryBean,我们调用它的getBean方法时,得到的是它的生成的对象,如果想得到Factory本身,需要在前面加上转义符“&”。上一篇我们在分析通过getBean方法触发的依赖注入过程时提到过,AbstractBeanFactory中的getObjectForBeanInstance方法中进行了对FactoryBean的相关处理,代码如下
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
//如果bean不是FactoryBean的实例并且以"&"开头就抛出异常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
//如果bean不是FactoryBean的实例或者是FactoryBean的实例并且以"&"开头就直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//这里从FactoryBean中取得Bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//如果BeanFactory为单例的并且已经被实例化过
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
//从缓存中获取
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//创建bean的具体实现
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (object != null && shouldPostProcess) {
//BeanPostProcessor中的方法只会处理FactoryBean而不会处理FactoryBean生成的对象,如果需要对生成的对象进行处理,可以自己覆盖这个方法
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
//在这里调用FactoryBean的getObject方法来生成需要的对象
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//在这里调用FactoryBean的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");
}
return object;
}
四、Spring自动装配(Autowire)的实现
我们前面分析的依赖关系一直是显式的配置在配置文件中来对bean的依赖关系进行管理的,Spring中还可以通过配置autowire属性来隐式的进行依赖关系的配置,IOC容器会根据autowire配置的属性来自动查找属性的名字或者类型来自动的完成依赖注入。利用这一特性可以简化配置文件中的配置,但是它也有一定的局限性,例如它不能自动装配基本类型、字符串、数组等,而且它进行的依赖注入是容器自己判断的,如果配置不当反而会有不好的效果,所以要谨慎使用。下面我们来看看这一特性是如何实现的。对于byName和byType两种配置方式的实现在AbstractAutowireCapableBeanFactory的populateBean方法中,这个方法在上一篇分析bean的依赖注入时有详细的说明
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//省略部分代码
···
//对autowire的byName和byType的处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//对于byName的处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 对byType的处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//省略部分代码
···
}
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//需要注入的属性名称
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//如果容器中包含指定名称的bean
if (containsBean(propertyName)) {
//触发属性的依赖注入
Object bean = getBean(propertyName);
//将需要注入的属性添加到PropertyValues中
pvs.add(propertyName, bean);
//注册bean的依赖关系
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
//获取需要注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
//获取注入的属性对应的PropertyDescriptor对象
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
if (Object.class != pd.getPropertyType()) {
//获取set方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//获取需要注入的属性对象
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
//将需要注入的属性添加到bean的PropertyValues中
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
对于autowire配置为constructor的相关处理在AbstractAutowireCapableBeanFactory的createBeanInstance方法中,这个方法用来生产具体的bean的对象,这个方法也在上一篇中有详细的说明,我们在这里只简单看看对这个配置的处理
//如果autowire配置为constructor,那么会调用对应的构造器来生成对象
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
对于SpringIOC的分析就到此结束了,下一篇开始分析Spring的AOP的实现。