美文网首页Spring中间件原理
spring源码探索(3)-IOC容器-Bean的一生

spring源码探索(3)-IOC容器-Bean的一生

作者: 青芒v5 | 来源:发表于2018-07-28 14:52 被阅读190次

前面的文章讲述了BeanDefinition的加载和注册,这些准备完毕后就开始了Bean的一生,如何创建、初始化、销毁等等。

生命周期

谈及Bean的生命周期其实也无非一个对象的周期,在IOC容器中Bean的生命周期主要有下面几个阶段
1.Bean实例的创建
2.为Bean实例设置属性
3.调用Bean的初始化方法
4.应用使用Bean
5.容器关闭时,销毁Bean


创建流程

下面针对关键步骤进行源码解读

Bean实例的创建

入口 getBean()
如果bean的 lazy-init=false,在容器启动的时候就会创建,true的时候当应用调用getBean()的时候才会创建。


|--AbstractBeanFactory.getBean
|----AbstractAutowireCapableBeanFactory.createBean
|------AbstractAutowireCapableBeanFactory.doCreateBean
|--------AbstractAutowireCapableBeanFactory.createBeanInstance
|----------AbstractAutowireCapableBeanFactory.instantiateBean
|------------SimpleInstantiationStrategy.instantiate


//AbstractAutowireCapableBeanFactory
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        //判断系统是否配置安全策略配置,这个是java SecurityManager 相关的东西,有兴趣的朋友可以自行看下
        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进行包装
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

//SimpleInstantiationStrategy
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
    // 判断methodOverrides是否为空来决定创建bean的策略
    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);
                }
            }
        }
        //java反射创建对象
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // 使用CGLIB 创建
        return instantiateWithMethodInjection(beanDefinition, beanName, owner);
    }
}

如何决策是使用jdk的反射创建对象还是cglib,取决于beanDefinition.getMethodOverrides()是否为空。这个methodOverrides是什么东西?

回顾下代码
BeanDefinitionParserDelegate.parseBeanDefinitionElement

parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

这两行代码,解析是 lookup-overridereplaced-method标签,这个两个标签使用的比较少,他们主要是为了bean的注入和执行有更灵活的选择,想了解的可以参考 使用说明

下面是两种实例化的策略代码

//利用java反射,构造方法实例化
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    try {
        ReflectionUtils.makeAccessible(ctor);
        return ctor.newInstance(args);
    }
    //.............................
}

//CGLIB 实例化
//CglibSubclassingInstantiationStrategy
protected Object instantiateWithMethodInjection(
        RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
    return new CglibSubclassCreator(beanDefinition, owner).instantiate(null, null);
}
//CglibSubclassingInstantiationStrategy.CglibSubclassCreator
public Object instantiate(Constructor<?> ctor, Object[] args) {
    //向Enhancer里设置生成java对象的参数,比如父类,命名规则、回调方法等
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(this.beanDefinition.getBeanClass());
    enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
    enhancer.setCallbackFilter(new CallbackFilterImpl());
    enhancer.setCallbacks(new Callback[] {
            NoOp.INSTANCE,
            new LookupOverrideMethodInterceptor(),
            new ReplaceOverrideMethodInterceptor()
    });

    //使用cglib的create生成实例化的bean
    return (ctor != null ? enhancer.create(ctor.getParameterTypes(), args) : enhancer.create());
}

上面是常规的创建bean的方式,还有一种所谓的FactoryBean,一种特殊的bean,通过工厂产出对应的bean。比如mybatis的SessionFactoryBean,就是一个应用场景。如何使用FactoryBean参考 使用方法

//AbstractBeanFactory
//AbstractBeanFactory
protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

    // 如果beanInstance不是FactoryBean类型则直接返回 
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        if (mbd == null && containsBeanDefinition(beanName)) {
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        //从factoryBean中得到bean
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}
//FactoryBeanRegistrySupport
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
            throws BeanCreationException {

    Object object;
    //省略代码
            //调用工厂方法
            object = factory.getObject();
    }
    //省略代码
    return object;
}

依赖注入


|--AbstractAutowireCapableBeanFactory.doCreateBean
|----AbstractAutowireCapableBeanFactory.populateBean
|------AbstractAutowireCapableBeanFactory.applyPropertyValues
|--------BeanDefinitionValueResolver.resolveValueIfNecessary


//AbstractAutowireCapableBeanFactory
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    //....................省略代码...........................
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    //记录每个属性的值
    List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    boolean resolveNecessary = false;
    for (PropertyValue pv : original) {
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        else {
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();

            //解析property 的value
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            boolean convertible = bw.isWritableProperty(propertyName) &&
                    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            // Possibly store converted value in merged bean definition,
            // in order to avoid re-conversion for every created bean instance.
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            else if (convertible && originalValue instanceof TypedStringValue &&
                    !((TypedStringValue) originalValue).isDynamic() &&
                    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    if (mpvs != null && !resolveNecessary) {
        mpvs.setConverted();
    }

    // 将解析好的 value,注入到 BeanWrapperImpl
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

解析value

//BeanDefinitionValueResolver
public Object resolveValueIfNecessary(Object argName, Object value) {
    // 判断value是否是ref 类型
    if (value instanceof RuntimeBeanReference) {
        RuntimeBeanReference ref = (RuntimeBeanReference) value;
        return resolveReference(argName, ref);
    }
    //判断value是否是bean的名字
    else if (value instanceof RuntimeBeanNameReference) {
        String refName = ((RuntimeBeanNameReference) value).getBeanName();
        refName = String.valueOf(evaluate(refName));
        if (!this.beanFactory.containsBean(refName)) {
            throw new BeanDefinitionStoreException(
                    "Invalid bean name '" + refName + "' in bean reference for " + argName);
        }
        return refName;
    }
    else if (value instanceof BeanDefinitionHolder) {
        // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
        BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
        return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
    }
    else if (value instanceof BeanDefinition) {
        // Resolve plain BeanDefinition, without contained name: use dummy name.
        BeanDefinition bd = (BeanDefinition) value;
        String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
                ObjectUtils.getIdentityHexString(bd);
        return resolveInnerBean(argName, innerBeanName, bd);
    }
    //数组
    else if (value instanceof ManagedArray) {
        // May need to resolve contained runtime references.
        ManagedArray array = (ManagedArray) value;
        Class<?> elementType = array.resolvedElementType;
        if (elementType == null) {
            String elementTypeName = array.getElementTypeName();
            if (StringUtils.hasText(elementTypeName)) {
                try {
                    elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
                    array.resolvedElementType = elementType;
                }
                catch (Throwable ex) {
                    // Improve the message by showing the context.
                    throw new BeanCreationException(
                            this.beanDefinition.getResourceDescription(), this.beanName,
                            "Error resolving array type for " + argName, ex);
                }
            }
            else {
                elementType = Object.class;
            }
        }
        return resolveManagedArray(argName, (List<?>) value, elementType);
    }
    //List
    else if (value instanceof ManagedList) {
        // May need to resolve contained runtime references.
        return resolveManagedList(argName, (List<?>) value);
    }
    //set
    else if (value instanceof ManagedSet) {
        // May need to resolve contained runtime references.
        return resolveManagedSet(argName, (Set<?>) value);
    }
    //map
    else if (value instanceof ManagedMap) {
        // May need to resolve contained runtime references.
        return resolveManagedMap(argName, (Map<?, ?>) value);
    }
    else if (value instanceof ManagedProperties) {
        Properties original = (Properties) value;
        Properties copy = new Properties();
        for (Map.Entry<Object, Object> propEntry : original.entrySet()) {
            Object propKey = propEntry.getKey();
            Object propValue = propEntry.getValue();
            if (propKey instanceof TypedStringValue) {
                propKey = evaluate((TypedStringValue) propKey);
            }
            if (propValue instanceof TypedStringValue) {
                propValue = evaluate((TypedStringValue) propValue);
            }
            copy.put(propKey, propValue);
        }
        return copy;
    }
    else if (value instanceof TypedStringValue) {
        // Convert value to target type here.
        TypedStringValue typedStringValue = (TypedStringValue) value;
        Object valueObject = evaluate(typedStringValue);
        try {
            Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
            if (resolvedTargetType != null) {
                return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
            }
            else {
                return valueObject;
            }
        }
        catch (Throwable ex) {
            // Improve the message by showing the context.
            throw new BeanCreationException(
                    this.beanDefinition.getResourceDescription(), this.beanName,
                    "Error converting typed String value for " + argName, ex);
        }
    }
    else {
        return evaluate(value);
    }
}

ref类型的解析在resolveReference(), List这些类型的最后也都会走到这个分支

private List<?> resolveManagedList(Object argName, List<?> ml) {
    List<Object> resolved = new ArrayList<Object>(ml.size());
    for (int i = 0; i < ml.size(); i++) {
        resolved.add(
                resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
    }
    return resolved;
}
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
    try {
        String refName = ref.getBeanName();
        refName = String.valueOf(evaluate(refName));
        if (ref.isToParent()) {
            if (this.beanFactory.getParentBeanFactory() == null) {
                throw new BeanCreationException(
                        this.beanDefinition.getResourceDescription(), this.beanName,
                        "Can't resolve reference to bean '" + refName +
                        "' in parent factory: no parent factory available");
            }
            //这里会向容器调用getBean方法
            return this.beanFactory.getParentBeanFactory().getBean(refName);
        }
        else {
            Object bean = this.beanFactory.getBean(refName);
            //保存bean的依赖关系
            this.beanFactory.registerDependentBean(refName, this.beanName);
            return bean;
        }
    }
    //省略若干代码
}

加载ref对应的bean,是通过名字调用容器的getBean方法,所以这个依赖注入其实也是一个大的递归调用。ref的bean get之后,不仅返回出去,同时也会调用 registerDependentBean, 这个方法的作用主要是记录bean的依赖关系。

DefaultSingletonBeanRegistry里的两个属性

beanName -> 被依赖的BeanNames
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

beanName -> 依赖的beanName
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

回到 AbstractAutowireCapableBeanFactory.applyPropertyValues
bw.setPropertyValues(new MutablePropertyValues(deepCopy)); 开始进行真正的注入动作。
AbstractAutowireCapableBeanFactory.setPropertyValues

//AbstractAutowireCapableBeanFactory
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
            throws BeansException {

    List<PropertyAccessException> propertyAccessExceptions = null;
    List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
            ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
    //循环bean的属性
    for (PropertyValue pv : propertyValues) {
        try {           
            setPropertyValue(pv);
        }
        //省略代码
    }

    // If we encountered individual exceptions, throw the composite exception.
    if (propertyAccessExceptions != null) {
        PropertyAccessException[] paeArray =
                propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
        throw new PropertyBatchUpdateException(paeArray);
    }
}

BeanWrapperImpl.setPropertyValue的代码太多了就不贴了,原理就是通过反射调用对象的set方法将属性设置进去。

初始化方法调用


|--AbstractAutowireCapableBeanFactory.doCreateBean
|----AbstractAutowireCapableBeanFactory.initializeBean


在完成bean的依赖注入之后,开始进行bean的初始化动作

//AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    
    //容器的aware接口的实现调用
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                invokeAwareMethods(beanName, bean);
                return null;
            }
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    //执行其spring容器的BeanPostProcessor.postProcessBeforeInitialization
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        //执行给bean配置的initMethod方法,如果bean实现了InitializingBean的接口,
        //则先调用afterPropertiesSet再调用initMethod
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }

    //执行其spring容器的BeanPostProcessor.postProcessAfterInitialization
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

这里涉及到一些spring的拓展点
aware接口,比如常用的
ApplicationContextAware 可以在bean中得到所在的上下文,从而直接应用
ApplicationEventPublisher 监听容器事件

BeanPostProcessor bean后置处理器。可以在spring容器中完成bean实例化、配置以及其他初始化方法前后添加一些逻辑处理

销毁

调用容器的destroy方法会触发bean的销毁动作。真正执行destory的地方在AbstractApplicationContext.doClose

protected void doClose() {
    boolean actuallyClose;
    synchronized (this.activeMonitor) {
        actuallyClose = this.active && !this.closed;
        this.closed = true;
    }

    if (actuallyClose) {
        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);
        }
        // Stop all Lifecycle beans, to avoid delays during individual destruction.
        try {
            getLifecycleProcessor().onClose();
        }
        catch (Throwable ex) {
            logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
        }

        // 销毁bean
        destroyBeans();
        //关闭容器
        closeBeanFactory();
        //留的钩子,子类可实现自己的方法
        onClose();

        synchronized (this.activeMonitor) {
            this.active = false;
        }
    }
}
//DefaultSingletonBeanRegistry
public void destroySingletons() {
    //省略代码

    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;
    }
}

对于java来说销毁一个对象,将它的引用依赖切断就行了,然后GC回收,所以对于spring容器来说,销毁bean也就是将自己缓存的map全部clear即可,不过spring也提供配置destroy-method,可以在销毁前调用配置的destroy-method方法。

|--DefaultSingletonBeanRegistry.destroySingleton
|----DefaultSingletonBeanRegistry.destroyBean
|------DisposableBeanAdapter.destroy

public void destroy() {
    //省略代码
    if (this.destroyMethod != null) {
        invokeCustomDestroyMethod(this.destroyMethod);
    }
    else if (this.destroyMethodName != null) {
        Method methodToCall = determineDestroyMethod();
        if (methodToCall != null) {
            invokeCustomDestroyMethod(methodToCall);
        }
    }
}

源码版本:3.2.18.RELEASE


系列文章
spring源码探索(0)-IOC容器-架构设计
spring源码探索(1)-IOC容器-Resource
spring源码探索(2)-IOC容器-BeanDefinition加载与注册
spring源码探索(3)-IOC容器-Bean的一生
[spring源码探索(4)-AOP实现原理]
(https://www.jianshu.com/p/485daf4acaa2)

相关文章

网友评论

    本文标题:spring源码探索(3)-IOC容器-Bean的一生

    本文链接:https://www.haomeiwen.com/subject/qzclpftx.html