spring技术内幕笔记--IOC容器的实现

IOC容器概述

Ioc容器和依赖反转模式

在面向对象系统中,对象封装了数据和对数据的处理,对象的依赖关系常体现在对数据和方法的依赖上。这些依赖关系可以可以通过把对象的依赖注入交给框架或IOC容器来完成,这样做可以在解耦代码的同时提高代码的可测试性。

Spring IOC的应用场景

在spring中,SpringIoC提供了一个基本的javaBean容器,通过IoC模式管理依赖关系,并通过依赖注入和AOP切面增强了为JavaBean这样的对象赋予事务管理,生命周期管理等基本功能。

在具体的注入实现中,接口注入,setter注入,构造器注入是主要的注入方式,其中相对而言setter注入更为常见。


Ioc容器的设计与实现:BeanFactory和ApplicationContext

spring ioc中有两个主要的容器,一个是实现了BeanFactory接口的简单容器系列;另一个是ApplicationContext应用上下文,是一种高级容器。

BeanFactory在Spring IoC容器体系中作为一个最基本的就扣类出现的。作为一个Spring IoC容器最基本的功能就是BeanFactory中定义的一系列行为。ApplicationContext同样不例外,也是通过实现BeanFactory实现的。但是ApplicationContext相对BeanFactory来说,要更为豪华,提供的功能要更多一些。

ioc容器的接口设计图
ioc容器的接口设计图

BeanFactory的应用场景和设计原理

//BeanFactory 接口提供的方法
public interface BeanFactory {
    /**
     * 用来引用一个实例,或把它和工厂产生的Bean区分开,就是说,如果一个FactoryBean的名字为a,那么,&a会得到那个Factory
     */
    String FACTORY_BEAN_PREFIX = "&";
    // 四个不同形式的getBean方法,获取实例
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;
    boolean containsBean(String name); // 是否存在bean
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 是否为单实例
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 是否为多实例
    boolean isTypeMatch(String name, Class<?> targetType)
            throws NoSuchBeanDefinitionException;// 名称、类型是否匹配
    Class<?> getType(String name) throws NoSuchBeanDefinitionException; // 获取类型
    String[] getAliases(String name);// 根据实例的名字获取实例的别名
}

具体依赖BeanFactory实现的类如XmlBeanFactory,这是一个元老级的类,从名字上很容易看出来这是个与xml有关的BeanFactory,XmlBeanFactory中定义了一个XmlBeanDefinationReader对象,通过这个对象读取在xml中定义的beanDefination,而后用BeanFactory接口实现对beanDefination的操作。

XmlBeanFactory是以DefaultListableBeanFactory为基类的,DefaultListableBeanFactory是一个很重要的IoC实现,在其他容器中,比如ApplicationContext实现也同XmlBeanFactory一样,通过持有或扩展DefaultListableBeanFactory来获得基本的IoC功能的。

ApplicationContext的应用场景和设计原理

ApplicationContext在提供了基本的IoC容器功能的基础上,还增添了许多新特性:

支持不同的信息源:ApplicationContext扩展了MessageSource接口,这些信息源的扩展性可以为开发多语言版本的应用提供服务。

访问资源:可以更加灵活的得到bean的定义信息。

支持应用事件:引入了事件机制,为Bean的管理提供了便利。

更多的附加服务:使得对ApplicationContext的使用是一种面向框架的风格。

ApplicationContext和BeanFacotry相比

ApplicationContext和BeanFacotry相比,提供了更多的扩展功能,但其主要区别在于后者是延迟加载(lazy-init)。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext则在初始化自身是检验,这样有利于检查所依赖属性是否注入;


IoC容器的初始化过程

IoC容器的初始化过程共分为三个步骤:

  1. Resource定位(Bean的定义文件定位)
  2. 将Resource定位好的资源载入到BeanDefinition
  3. 将BeanDefiniton注册到容器中

Resource定位

这个Resource定位指的是BeanDefinition的资源定位,它由ResourceLoader通过统一的Resource接口来完成,这个Resource对各种形式的BeanDefinition的使用提供了统一接口。对于这些BeanDefinition的存在形式,相信大家都不会感到陌生。比如说,在文件系统中的Bean定义信息可以使用FileSystemResource来进行抽象;在类路径中可以使用前面提到的ClassPathResource来使用,等等。这个过程类似于容器寻找数据的过程,就像用水桶装水先要把水找到一样。

定位的资源载入到BeanDefinition

该载入过程把用户定义好的Bean表示成IoC容器内部的数据结构,而这个容器内部的数据结构就是BeanDefinition。总地说来,这个BeanDefinition实际上就是对象在IoC容器中的抽象,这个BeanDefinition定义了一系列的数据来使得IoC容器能够方便地对对象也就是Spring的Bean进行管理。即BeanDefinition就是Spring的领域对象。

载入过程相当于把定义的 BeanDefinition 在IoC容器中转化为一个Spring内部表示的数据结构的过程。IoC容器对Bean的管理和依赖注入功能的实现,是通过对其持有的BeanDefinition 进行各种操作来完成的。

将BeanDefiniton注册到容器中

BeanDefinition 在IoC容器中完成了载入和解析后,用户定义的 BeanDefinition 信息已经在IoC容器内建立起了自己的数据结构以及相应的数据表示,但此时这些数据还不能供IoC容器直接使用,需要在IoC容器中对这些 BeanDefinition 数据进行注册。

这个注册为IoC容器提供了更友好的使用方式,在 DefaultListableBeanFactory 中,是通过一个 ConcurrentHashMap 来持有载入的 BeanDefinition 的。


初始化总结

 IoC容器初始化的入口是在构造方法中调用refresh()开始的,具体过程如下图中代码展示:

img_c818cc1f96997678c224491568f54e8f.png

通过ResourceLoader来完成资源文件位置的定位,DefaultResourceLoader是默认的实现,同时上下文本身就给出了ResourceLoader的实现。

创建的IoC容器是DefaultListableBeanFactory。

IoC容器对Bean的管理和依赖注入功能的实现是通过对其持有的BeanDefinition进行相关操作来完成的。 通过BeanDefinitionReader来完成定义信息的解析和Bean信息的注册。

XmlBeanDefinitionReader是BeanDefinitionReader的实现类,通过它来解析XML配置中的bean定义。 实际的处理过程是委托给 BeanDefinitionParserDelegate来完成的。

得到bean的定义信息,这些信息在Spring中使用BeanDefinition对象来表示。

BeanDefinition的注册是由BeanDefinitionRegistry实现的registerBeanDefinition方法进行的。内部使用ConcurrentHashMap来保存BeanDefinition。


IoC容器的依赖注入

BeanFactory中有个getBean方法,依赖注入的过程是用户第一次向IoC容器索要Bean是触发的,当然也可以通过懒加载机制实现bean的预实例化。通过getBean获取的bean不是简单的java对象,而是已经包含了对象之间依赖关系的Bean。

下面从DefaultListableBeanFactory中的getBean入手,来看看getBean方法是如何实现的。

getBean方法内部依赖doGetBean方法实现:

protected <T> T doGetBean(
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
        throws BeansException {
    // 1.解析beanName,主要是解析别名、去掉FactoryBean的修饰符“&”
    final String beanName = transformedBeanName(name);
    Object bean;
 
    // Eagerly check singleton cache for manually registered singletons.
    // 2.尝试从缓存中获取beanName对应的实例
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        // 3.如果beanName的实例存在于缓存中
        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 + "'");
            }
        }
        // 3.1 返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
 
    else {
        // Fail if we're already creating this bean instance: 如果我们已经创建了这个bean实例,则会失败:我们可能会在循环引用中。
        // We're assumably within a circular reference.
        // 4.scope为prototype的循环依赖校验,如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常
        // 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
 
        // Check if bean definition exists in this factory.
        // 5. 如果parentBeanFactory对象存在,并且该beanName在当前BeanFactory的beanDefinitionMap缓存中不存在,则尝试从parentBeanFactory中检测
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            // 5.2 将别名解析成真正的beanName
            String nameToLookup = originalBeanName(name);
            // 5.3 尝试在parentBeanFactory中获取bean对象实例
            if (args != null) {
                // Delegation to parent with explicit args.
                // 5.3.1 使用父工厂调用getBean创建bean对象实例
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                // 5.3.2 使用父工厂调用getBean创建bean对象实例
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }
 
        if (!typeCheckOnly) {
            // 6.如果不是仅仅做类型检测,则是创建bean实例,这里要将beanName标记为已经创建bean实例(即将beanName添加到alreadyCreated缓存)
            markBeanAsCreated(beanName);
        }
 
        try {
            // 7.根据beanName重新获取合并的BeanDefinition(步骤6将合并的BeanDefinition删除了,这边获取一个新的)
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 7.1 检查合并的BeanDefinition
            checkMergedBeanDefinition(mbd, beanName, args);
 
            // Guarantee initialization of beans that the current bean depends on.
            // 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                // 8.1 遍历当前bean依赖的bean名称集合
                for (String dep : dependsOn) {
                    // 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
                    if (isDependent(beanName, dep)) {
                        // 8.3 如果是循环依赖则抛异常
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 8.4 将dep和beanName的依赖关系注册到缓存中
                    registerDependentBean(dep, beanName);
                    // 8.5 获取dep实例,如果dep还没有创建bean实例,则创建dep的bean实例(执行dep的bean加载操作)
                    getBean(dep);
                }
            }
 
            // Create bean instance.
            // 9.针对不同的scope进行bean的创建
            if (mbd.isSingleton()) {
                // 9.1 scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    @Override
                    public Object getObject() throws BeansException {	//
                        try {
                            // 9.1.1 创建Bean实例
                            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;
                        }
                    }
                });
                // 9.1.2 返回beanName对应的实例对象
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
 
            else if (mbd.isPrototype()) {
                // 9.2 scope为prototype的bean创建
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    // 9.2.1 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
                    beforePrototypeCreation(beanName);
                    // 9.2.2 创建Bean实例
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    // 9.2.3 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
                    afterPrototypeCreation(beanName);
                }
                // 9.2.4 返回beanName对应的实例对象
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }
 
            else {
                // 9.3 其他scope的bean创建,可能是request之类的
                // 9.3.1 根据scopeName,从缓存拿到scope实例
                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 {
                    // 9.3.2 其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            // 9.3.3 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
                            beforePrototypeCreation(beanName);
                            try {
                                // 9.3.4 创建bean实例
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                // 9.3.5 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    // 9.3.6 返回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) {
            // 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }
 
    // Check if required type matches the type of the actual bean instance.
    // 10.检查所需类型是否与实际的bean对象的类型匹配
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
        try {
            // 10.1 类型不对,则尝试转换bean类型
            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());
        }
    }
    // 11.返回创建出来的bean实例对象
    return (T) bean;
}

getBean是依赖注入的起点,之后会调用createBean,createBean是通过doCreateBean方法实现的。

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean '" + beanName + "'");
    }
    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.
    // 1.解析beanName对应的Bean的类型,例如:com.joonwhee.open.demo.service.impl.UserServiceImpl
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        // 如果resolvedClass存在,并且mdb的beanClass不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name),
        // 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性,
        // 该拷贝副本取代mdb用于后续的操作
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }
 
    // Prepare method overrides.
    try {
        // 2.验证及准备覆盖的方法(对override属性进行标记及验证)
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }
 
    try {
        // 3.如果bean配置了postProcessor,这里返回的是一个proxy
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        // 4.如果经过实例化前的处理后返回的bean实例不为空,那么会直接略过后续的Bean的创建而直接使用返回的bean实例
        if (bean != null) {
            return bean;
        }
    } catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }
    // 5.创建Bean实例(do开头,真正创建Bean的方法)
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isDebugEnabled()) {
        logger.debug("Finished creating instance of bean '" + beanName + "'");
    }
    // 6.返回创建的Bean实例
    return beanInstance;
}

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
        throws BeanCreationException {
 
    // Instantiate the bean.
    // 1.新建Bean包装类
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 2.如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 3.根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 4.拿到创建好的Bean实例
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    // 5.拿到Bean实例的类型
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    mbd.resolvedTargetType = beanType;
 
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改合并的BeanDefinition,
                // Autowired注解正是通过此方法实现注入类型的预解析
                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.
    // 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前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");
        }
 
        // 8.提前曝光beanName的ObjectFactory,用于解决循环引用
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                // 8.1 应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,
                // 若没有则直接返回bean,对于我们熟知的AOP就是在这里将advice动态织入bean中
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }
 
    // Initialize the bean instance.  初始化bean实例。
    Object exposedObject = bean;
    try {
        // 9.对bean进行填充,将各个属性值注入;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖bean
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            // 10.对bean进行初始化
            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) {
        // 11.如果允许提前曝光实例,则进行循环依赖检查
        Object earlySingletonReference = getSingleton(beanName, false);
        // 11.1 earlySingletonReference只有在当前解析的bean存在循环依赖的情况下才会不为空
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                // 11.2 如果exposedObject没有在initializeBean方法中被增强,则不影响之前的循环引用,继续往下走
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                // 11.3 如果exposedObject在initializeBean方法中被改变了,
                // 并且允许注入的bean被包装过 并且 当前bean有被其他bean依赖
 
                // 11.4 拿到依赖当前bean的所有bean的beanName数组
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    // 11.5 尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        // 11.6 移除失败的添加到 actualDependentBeans
                        actualDependentBeans.add(dependentBean);
                    }
                }
 
                if (!actualDependentBeans.isEmpty()) {
                    // 11.7 如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据”
                    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 {
        //
        // 12.注册DisposableBean:处理destroy方法,有三种:自定义、实现DisposableBean接口、存在DestructionAwareBeanPostProcessor
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    // 13.完成创建并返回
    return exposedObject;

结合上述再次理解一下bean的生命周期

IoC容器找到配置文件中定义的Spring Bean,即资源定位;

IoC容器利用Java反射或者CGLIB创建一个Bean的实例,其中包括createBean(),createBeanInstance()等方法的实现;

如果涉及到一些属性值,会进行一些属性值的注入;

如果实现了其他什么Aware接口,就调用相应的方法,一般来说bean不需要了解IoC容器的状态的,而某些情况下,是需要bean对IoC进行操作的,这个时候就通过特定的aware借口来实现:

比如,Bean实现了BeanNameAware接口, 可以得到该bean在容器中的实例名称 ;

比如,Bean实现了BeanFactoryAware接口,可以在bean中得到bean所在的容器,从而使用容器提供的服务;

如果 Bean有设置对应的PostProcessor,那么 将调用该接口 的postProcessBeforeInitialzation() 方法 对 bean进行加工操作,这个是用来实现 spring 的 AOP的。针对所有Spring上下文中所有的bean,可以在配置文件中配置一个BeanPostProcessor,然后对所有的bean进行一个初始化之前和之后的代理。

如果Bean在配置文件中的定义包含init-method属性,执行指定的初始化方法;

如果 Bean有设置对应的PostProcessor,初始化bean之后,执行postProcessAfterInitialization()方法。做初始化之后的增强;

通过ioc容器使用bean;

容器关闭时销毁bean的方法:Bean先执行destroy()方法;如果Bean在配置文件中的定义包含destroy-method属性,执行自定义销毁的方法。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值