【技术分享】-Spring的IOC

来源:互联网 发布:spss输入数据 编辑:程序博客网 时间:2024/06/08 17:54

Spring的IOC


一. 什么是控制反转,为什么叫控制反转

控制反转:就是把原先我们代码里面需要自己手动实现的对象创建、依赖的代码,反转给容器来帮忙实现。

IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象只需要关心业务逻辑本身就可以了。从这方面来说,对象如何得到他的协作对象的责任被反转了(IOC、DI)。

二. IOC依赖注入的方式有哪些?

主要有三种注入方式:

(1)接口注入

(2)setter注入

(3)构造器注入

三. IOC容器实现中的屌丝和高富帅

基于Spring 4.3

3.1 BeanFactory

BeanFactory 是最基本的容器形态,只实现了容器最基本的功能。

下面先给出这个接口的定义:

public interface BeanFactory {    /**     * 用于与FactoryBean创建的bean区别. 比如有一个叫做 myBean的FactoryBean,调用getBean(&myBean) 返回的是factory而不是被factory创建的实例。     */    String FACTORY_BEAN_PREFIX = "&";    /**     * 返回一个指定的bean实例,其是共享的或则是独占的。     */    Object getBean(String name) throws BeansException;    /**     * 返回一个指定的bean实例,其是共享的或则是独占的。其增加了类型检查。     */     <T> T getBean(String name, Class<T> requiredType) throws BeansException;    /**     * 返回一个指定的bean 单例实例,其类型必须是指定的Class类型。     */    <T> T getBean(Class<T> requiredType) throws BeansException;    /**     * 根据name 判断当前beanFactory是否包含这个bean的定义或则是已注册的单例实例。     */    boolean containsBean(String name);    /**     * 根据name 判断当前bean是不是共享的单例bean     */    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;    /**     * 根据name 判断当前bean是不是多例bean     */    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;    /**     * 根据name 和class 进行类型检查     */    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;    /**     * 根据name 获取这个bean对应的Class类型。     */    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;    /**     * 返回给定name 对应的bean的所有的别名,     */    String[] getAliases(String name);}

上面一共列出了9个接口,这9个接口就是IOC 容器提供的最基本的功能。

3.2ApplicationContext

ApplicationContext 是 IOC 容器的高级形态

ApplicationContext继承于BeanFactory接口,此外还继承了MessageSource、ResourceLoader、ApplicationEventPublisher等接口,因此有比BeanFactory多的高级功能:

(1)MessageSource接口支持不同信息源,支持国际化

(2)ResourceLoader接口支持访问资源(加载资源),下面给出ResourceLoader和其子接口ResourcePatternResolver的具体method

public interface ResourceLoader {    //加载资源路径的前缀, 此处是“classpath:”    String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;    /**     * 获取指定资源路径的 Resource对象     */    Resource getResource(String location);    /**     * 暴露此ResourceLoader使用的ClassLoader。     */    ClassLoader getClassLoader();}
public interface ResourcePatternResolver extends ResourceLoader {    //来自类路径的所有匹配资源的伪URL前缀,与“classpath:”不同点在于它会检索所有匹配上的资源    String CLASSPATH_ALL_URL_PREFIX = "classpath*:";    /**     * 将给定的路径下的所有资源解析为资源对象。     */    Resource[] getResources(String locationPattern) throws IOException;}

(3)支持应用事件(继承了ApplicationEventPublisher)

public interface ApplicationEventPublisher {    /**     * 通知所有注册在应用程序事件中匹配的监听器。事件可以是框架事件(例如RequestHandledEvent)或特定于应用程序的事件。     */    void publishEvent(ApplicationEvent event);    /**     * 通知在此应用程序注册的所有匹配的监听器。     * 如果指定的事件不是ApplicationEvent, event就会被包装成PayloadApplicationEvent     */    void publishEvent(Object event);}

四. Spring IOC 中涉及到的核心接口类。

1)BeanFactory接口:基本的容器形态

2)ApplicationContext接口:高级容器形态

3)BeanDefination接口:Bean的数据结构,里面定义了bean的依赖关系。

4)BeanPostProcessor 接口

5)BeanFactoryPostProcessor 接口

6)SpringApplicationRunListener接口,在springboot中的实现类是EventPublishingRunListener。

(相关的类有SpringApplicationRunListeners、ApplicationEventMulticaster(EventPublishingRunListener实际上是通过Spring的ApplicationEventMulticaster广播器实现的))

4.1 ApplicationContext接口

ApplicationContext是IOC容器的高级形态,提供了很多高级功能,从下图的类图可以看到,ApplicationContext通过继承了MessageSource、ResourceLoader、ApplicationEventPublisher等接口,从而实现了比BeanFactory简单IOC容器更加高级的一些特性的支持。

ApplicationContext

4.2 BeanDefinition接口

Spring通过定义BeanDefinition来管理基于Spring的应用中的各种对象以及它们之间的相互依赖关系。 BeanDefinition抽象了对Bean的定义,是让容器起作用的主要数据结构。BeanDefinition管理了对象依赖关系,是IOC容器实现依赖反转功能的核心数据结构,依赖反转功能都是围绕BeanDefinition的处理来完成的。

BeanDefinition是一个接口,其实现有多个,看一下实现子类图:

这里写图片描述

AbstractBeanDefinition是一个抽象的实现类,这个抽象类的子类有ChildBeanDefinition、RootBeanDefinition、GenericBeanDefinition。这三个类是经常使用的。

下面先从BeanDefinition接口出发,然后分析AbstractBeanDefinition等实现类的数据域。最后理清楚Bean的数据结构。

BeanDefinition

这个接口里面定义了一些常用的常量,这些常量对实现类是开放的,下面给出了两个最重要的常量:

/** * 标识这是一个单例的bean */String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;/** * 标识这是一个多例的bean */String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

AbstractBeanDefinition是BeanDefinition的抽象实现类,是BeanDefinition实现的最核心的部分,也是ChildBeanDefinition、RootBeanDefinition、GenericBeanDefinition的公共基类。

下面看看AbstractBeanDefinition是怎么实现Bean的依赖关系的数据结构,这里只给出了最核心的property来表示数据结构:

/** * 常量:默认的SCOPE,  */public static final String SCOPE_DEFAULT = "";/** * 常量:表示不自动载入。 */public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;/** * 常量:按name自动注入bean */public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;/** * 常量:按bean的type自动注入bean */public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;/** * 常量:按bean的构造器自动注入bean */public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;/** * 常量:不进行依赖检查 */public static final int DEPENDENCY_CHECK_NONE = 0;/** * 常量:对引用对象进行依赖检查 */public static final int DEPENDENCY_CHECK_OBJECTS = 1;/** * 常量:对简单数据类型属性进行依赖检查 */public static final int DEPENDENCY_CHECK_SIMPLE = 2;/** * 常量:对所有数据类型变量进行依赖检查  */public static final int DEPENDENCY_CHECK_ALL = 3;/** bean对象 */private volatile Object beanClass;/** 默认的SCOPE */private String scope = SCOPE_DEFAULT;/** 是否延迟加载标志位 */private boolean lazyInit = false;/** bean的注入类型 */private int autowireMode = AUTOWIRE_NO;/** bean的依赖检查类型 */private int dependencyCheck = DEPENDENCY_CHECK_NONE;/** 当前bean所依赖的其余bean的数组 */private String[] dependsOn;private String factoryBeanName;private String factoryMethodName;/** 默认的ROlE, 也就是用户自定义的bean,用于应用程序 */private int role = BeanDefinition.ROLE_APPLICATION;

RootBeanDefinition

ChildBeanDefinition

ChildBeanDefinition这个类是继承于AbstractBeanDefinition, 唯一多了一个属性域:

// 父beanDefinitionprivate String parentName;

4.3 Spring的事件机制

Spring的事件机制主要包括三个部分:

1)事件:ApplicationEvent,类似于消息。

2)事件监听器:ApplicationListener,对监听到的事件进行处理,类似于观察者。

3)事件广播器:ApplicationEventMulticaster,将Spring publish的事件广播给所有的监听器,类似于消息的发布者。

上面的三种角色和观察者模式很像,监听器类似于观察者,广播器类似于发布者,事件类似于消息传递的媒介。

Springboot中的事件机制

在SpringBoot中有一个叫做 SpringApplicationRunListeners 的类,这个类其实就是维护了一个SpringApplicationRunListener 列表,也就是Spring的Application的运行监听器的列表,看一下 SpringApplicationRunListeners 类里面的属性:

// 类属性,其实就是一个SpringApplicationRunListener的listprivate final List<SpringApplicationRunListener> listeners;//构造器SpringApplicationRunListeners(Log log,        Collection<? extends SpringApplicationRunListener> listeners) {    this.listeners = new ArrayList<SpringApplicationRunListener>(listeners);}

SpringApplicationRunListener 这个接口是Springboot中的接口,具体的方法如下:

public interface SpringApplicationRunListener {    /**     *运行方法第一次启动时被立即调用。     */    void started();    /**     * 在ApplicationContext 被创建之前被调用一次,准备环境。     */    void environmentPrepared(ConfigurableEnvironment environment);    /**     * 在ApplicationContext被创建之后且在加载source之前被调用一次     */    void contextPrepared(ConfigurableApplicationContext context);    /**     * 在application context 已经被load 但是还没有refreshed之前被调用一次。     */    void contextLoaded(ConfigurableApplicationContext context);    /**     * 在运行方法完成之前被立即调用     */    void finished(ConfigurableApplicationContext context, Throwable exception);}

SpringApplicationRunListener在springboot中的默认实现类是EventPublishingRunListener,看一下这个类的源码如下:

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {    //Springboot中的SpringApplication    private final SpringApplication application;    private final String[] args;    //这个是Spring framework中的Application 事件广播器,类似于事件广播器    private final ApplicationEventMulticaster initialMulticaster;    /**     *构造器     */    public EventPublishingRunListener(SpringApplication application, String[] args) {        this.application = application;        this.args = args;        this.initialMulticaster = new SimpleApplicationEventMulticaster();        for (ApplicationListener<?> listener : application.getListeners()) {            this.initialMulticaster.addApplicationListener(listener);        }    }    @Override    public int getOrder() {        return 0;    }    //发布ApplicationStartedEvent事件    @Override    public void started() {        this.initialMulticaster                .multicastEvent(new ApplicationStartedEvent(this.application, this.args));    }    //发布ApplicationEnvironmentPreparedEvent事件    @Override    public void environmentPrepared(ConfigurableEnvironment environment) {        this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(                this.application, this.args, environment));    }    @Override    public void contextPrepared(ConfigurableApplicationContext context) {    }    //发布ApplicationPreparedEvent事件    @Override    public void contextLoaded(ConfigurableApplicationContext context) {        for (ApplicationListener<?> listener : this.application.getListeners()) {            if (listener instanceof ApplicationContextAware) {                ((ApplicationContextAware) listener).setApplicationContext(context);            }            context.addApplicationListener(listener);        }        this.initialMulticaster.multicastEvent(                new ApplicationPreparedEvent(this.application, this.args, context));    }    // 发布ApplicationReadyEvent事件    @Override    public void finished(ConfigurableApplicationContext context, Throwable exception) {        // Listeners have been registered to the application context so we should        // use it at this point        context.publishEvent(getFinishedEvent(context, exception));    }    private SpringApplicationEvent getFinishedEvent(            ConfigurableApplicationContext context, Throwable exception) {        if (exception != null) {            return new ApplicationFailedEvent(this.application, this.args, context,                    exception);        }        return new ApplicationReadyEvent(this.application, this.args, context);    }}

从上面EventPublishingRunListener源码我们知道,SpringBoot中的发布事件都是借助于Spring Framework中的ApplicationEventMulticaster这个事件广播器实现的,ApplicationEventMulticaster这个接口里面有三个主要的方法:

/** * 添加一个监听器去通知所有的事件 */void addApplicationListener(ApplicationListener<?> listener);/** * 从通知列表中删除一个监听器listener */void removeApplicationListener(ApplicationListener<?> listener);/** * 广播给定的应用事件给适当的监听器。 */void multicastEvent(ApplicationEvent event);

这一套事件监听机制非常类似于订阅发布的模式:

ApplicationEventMulticaster 就像是广播发布者;
SpringApplicationRunListener 就像是订阅者来监听事件;
ApplicationEvent 就是传递的事件消息。

对于ApplicationEventMulticaster的实现类,有一个抽象类AbstractApplicationEventMulticaster和一个SimpleApplicationEventMulticaster类。核心的实现数据结构在AbstractApplicationEventMulticaster中。这里以上面ApplicationEventMulticaster的三个核心函数为例来讲解。下面贴出核心源码:

// 成员变量//监听事件接收器private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);//缓存final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =    new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);//锁private Object retrievalMutex = this.defaultRetriever;//函数实现/** * 同步加锁,线程安全实现add 一个 ApplicationListener到 容器中 */@Overridepublic void addApplicationListener(ApplicationListener<?> listener) {    synchronized (this.retrievalMutex) {        this.defaultRetriever.applicationListeners.add(listener);        this.retrieverCache.clear();    }}@Overridepublic void removeApplicationListener(ApplicationListener<?> listener) {    synchronized (this.retrievalMutex) {        this.defaultRetriever.applicationListeners.remove(listener);        this.retrieverCache.clear();    }}/** * 核心就是获取所有匹配的事件类型的监听器,然后分别在每个监听器上调用invokeListener(listener, event); 实现在每个监听器上执行监听事件的函数 */public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {        Executor executor = getTaskExecutor();        if (executor != null) {            executor.execute(new Runnable() {                @Override                public void run() {                    invokeListener(listener, event);                }            });        }        else {            invokeListener(listener, event);        }    }}

上面类中最重要成员变量就是ListenerRetriever defaultRetriever ,这个类里面维护了一个ApplicationListener的Set集合,用来存储所有的事件监听器,源码如下:

public final Set<ApplicationListener<?>> applicationListeners;

所以defaultRetriever 的角色就是一个ApplicationListener的元素去重容器的管理者。

五. IOC容器的初始化原理分析


对于Spring的IOC的分析还得从org.springframework.context.support.AbstractApplicationContext#refresh()函数开始分析,这里才是启动Spring的核心地方。

首先做一个overview,贴出这个函数的源码:

public void refresh() throws BeansException, IllegalStateException {    synchronized (this.startupShutdownMonitor) {        //1.Prepare this context for refreshing.        prepareRefresh();        //2.Tell the subclass to refresh the internal bean factory.        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();        // Prepare the bean factory for use in this context.        prepareBeanFactory(beanFactory);        try {            // Allows post-processing of the bean factory in context subclasses.            postProcessBeanFactory(beanFactory);            // Invoke factory processors registered as beans in the context.            invokeBeanFactoryPostProcessors(beanFactory);            // Register bean processors that intercept bean creation.            registerBeanPostProcessors(beanFactory);            // Initialize message source for this context.            initMessageSource();            // Initialize event multicaster for this context.            initApplicationEventMulticaster();            // Initialize other special beans in specific context subclasses.            onRefresh();            // Check for listener beans and register them.            registerListeners();            // Instantiate all remaining (non-lazy-init) singletons.            finishBeanFactoryInitialization(beanFactory);            // Last step: publish corresponding event.            finishRefresh();        }        catch (BeansException ex) {            if (logger.isWarnEnabled()) {                logger.warn("Exception encountered during context initialization - " +                        "cancelling refresh attempt: " + ex);            }            // Destroy already created singletons to avoid dangling resources.            destroyBeans();            // Reset 'active' flag.            cancelRefresh(ex);            // Propagate exception to caller.            throw ex;        }        finally {            // Reset common introspection caches in Spring's core, since we            // might not ever need metadata for singleton beans anymore...            resetCommonCaches();        }    }}

这里refresh() 是加锁了的,避免了多线程刷新Spring的applicationContext的时候产生冲突。其二代码隔离做的非常好,用了很多个方法封装一部分逻辑实现,下面分别对其中各个方法主要逻辑做分析:

invokeBeanFactoryPostProcessors(beanFactory); 这个函数中实现了加载 bean 的 definition。

1.BeanDefinition的Resource定位

通过 ResourceLoader 这个类来完成。

2.BeanDefinition的载入和解析

把用户的Bean 表示成IOC容器内部数据结构(BeanDefination)

BeanDefinitionReader主要是载入Bean;
RegisterBeanDefinition 主要是用来解析并转化为内部数据结构。

载入和解析完成以后,BeanDefinition信息已经在IOC容器内建立起自己的数据结构以及相应的数据表示。

3.BeanDefinition的注册

向IOC容器中注册这些BeanDefination过程,通过BeanDefinationRegistry接口实现完成,实质上是注册到一个HashMap

六. IOC容器的DI依赖注入

IOC 容器的初始化建立了 BeanDefinition 数据映射,但是并没有对Bean依赖关系进行注入。

(1)第一次通过getBean() IOC容器触发依赖注入(也有例外,比如lazy-init)

(2)依赖注入分为两个过程

1. createBeanInstance()  创建bean对应的Java实例2. populateBean()  填充bean然后依赖注入进行处理

createBean() 会依据BeanDefinition定义要求来生成Bean。

在Bean创建和对象依赖注入的过程中,需要依据BeanDefinition中的信息来递归地完成依赖注入。递归都是以getBean()函数为入口的,在依赖注入的过程中涉及到三个递归地过程:

1)一个递归是在上下文体系中查找需要的Bean和创建Bean的递归调用。

2)另一个递归是在依赖注入时,通过递归调用容器的getBean()方法,得到当前Bean的依赖的Bean,同时触发对依赖的Bean的创建和注入。

3)对Bean的属性进行依赖注入时,解析的过程也是一个递归地过程。

这样根据依赖关系,一层一层完成Bean的创建和注入,直到最后完成当前Bean的创建。有了这个顶层Bean的创建和对它属性的依赖注入的完成,意味着和当前Bean相关的整个依赖链的注入也完成了。

下面从源码的角度分析整体的流程。

下面以 springApplication.getBean("domainMapper"); 这行代码开始分析依赖注入。

@Overridepublic Object getBean(String name) throws BeansException {    //检验当前context是否处于激活的状态。    assertBeanFactoryActive();    return getBeanFactory().getBean(name);}

下面再看 getBeanFactory().getBean(name);

这行代码的作用是:首先调用的是 getBeanFactory() 这个函数,获取的是IOC容器里面的BeanFactory,在这里实际上就是 DefaultListableBeanFactory,然后实际上就是调用

AbstractBeanFactory.getBean(String name)

源码如下:

public Object getBean(String name) throws BeansException {    return doGetBean(name, null, null, false);}

可知就是调用了 doGetBean(name, null, null, false); 函数, 这里才是真正实现IOC容器依赖注入的地方,源码比较长,就只保留核心的源码,我这里先粘贴出来doGetBean()方法的部分核心方法:

/** * 返回一个指定的bean实例,其可能是共享的,也可能是独立的实例。 * @param name 检索bean的name * @param requiredType 检索bean的对象类型 * @param args 使用显式参数创建bean实例时使用的参数 * (仅仅在创建一个新的实例的时候使用,而不是在检索一个已存在的实例的时候使用。) * @param typeCheckOnly 标识获得的实例是否进行类型检查。 * @return 返回一个bean的实例 */protected <T> T doGetBean(        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)        throws BeansException {    // 对beanName做一些处理,获取真实的 beanName    final String beanName = transformedBeanName(name);    // 这是最后返回的beanName    Object bean;    // 根据 beanName 从缓存中获取单例对象    Object sharedInstance = getSingleton(beanName);    // 如果单例非空,且没有参数。    if (sharedInstance != null && args == null) {        // 通过给定的获bean对象获取实例。        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);    }    /**      *       */    else {        //这里对IOC容器中的BeanDefintion是否存在做检查,现在当前BeanFactory中去取,如果取不到就再去双亲的BeanFactory中去取。如果双亲也取不到,就顺着双亲BeanFactory链一直向上查找。        BeanFactory parentBeanFactory = getParentBeanFactory();        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {            // Not found -> check parent.            String nameToLookup = originalBeanName(name);            if (args != null) {                //递归授权给双亲的BeanFactory去查找Bean                return (T) parentBeanFactory.getBean(nameToLookup, args);            }            else {                //递归授权给双亲的BeanFactory去查找Bean                return parentBeanFactory.getBean(nameToLookup, requiredType);            }        }        try {            //这里根据Bean的名字取得 BeanDefinition            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);            checkMergedBeanDefinition(mbd, beanName, args);            // 这里会获取当前Bean的所有依赖的Bean,这会触发递归调用 getBean()方法,知道Bean没有任何依赖的Bean。            String[] dependsOn = mbd.getDependsOn();//获取当前ben的依赖的bean            if (dependsOn != null) {                for (String dep : dependsOn) {                    if (isDependent(beanName, dep)) {                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");                    }                    registerDependentBean(dep, beanName);                    getBean(dep);                }            }            //这里会调用createBean()方法来创建singleton bean实例,在回调函数getObject()中会调用createBean(beanName, mbd, args);方法            if (mbd.isSingleton()) {                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {                    @Override                    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);            }            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);            }            //这里是创建prototype bean的地方。            else {                String scopeName = mbd.getScope();                final Scope scope = this.scopes.get(scopeName);                if (scope == null) {                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");                }                try {                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {                        @Override                        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);                }            }        }        catch (BeansException ex) {            cleanupAfterBeanCreationFailure(beanName);            throw ex;        }    }    //这里对创建的 Bean进行类型检查,类型检查通过才会返回这个新创建的Bean实例。    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;}

针对上面函数实现体中的一些重要实现做分析:

(1)getSingleton(beanName);

当我们需要获取的bean已经被注入实例化了,就会存储在缓存中,这个函数就是根据beanName在缓存的Map

protected Object getSingleton(String beanName, boolean allowEarlyReference) {    // 尝试从一个Map缓存中获取单例对象    Object singletonObject = this.singletonObjects.get(beanName);    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {        synchronized (this.singletonObjects) {            singletonObject = this.earlySingletonObjects.get(beanName);            if (singletonObject == null && allowEarlyReference) {                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);                if (singletonFactory != null) {                    singletonObject = singletonFactory.getObject();                    this.earlySingletonObjects.put(beanName, singletonObject);                    this.singletonFactories.remove(beanName);                }            }        }    }    return (singletonObject != NULL_OBJECT ? singletonObject : null);}

首先尝试从this.singletonObjects 这个缓存Map 中获取单例对象,这个Map的定义如下:

// DefaultSingletonBeanRegistry类中/** Cache of singleton objects: bean name --> bean instance */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

1)如果能够从缓存中获取到单例对象,就直接返回;

2)如果不能获取到,说明还没缓存在单例Map中,就进行判断

singletonObject == null && isSingletonCurrentlyInCreation(beanName)

这个 if 的判断条件判断 singletonObject为null 且并且这个单例正在创建中。就通过获取singletonFactory, 然后调用singletonFactory.getObject();创建单例。

最终结果就是获取单例的Bean。

(2)getObjectForBeanInstance(sharedInstance, name, beanName, null);

当获取到bean instance之后就会
这个函数根据给定的 bean Instance 实例,获取 Object.

(1)如果这个 sharedInstance 是一个FactoryBean, 那么我们就利用这个FactoryBean来创建一个bean instance。

实现如下:
1)首先调用 getCachedObjectForFactoryBean(beanName); 来从Map缓存中获取Object:

protected Object getCachedObjectForFactoryBean(String beanName) {    Object object = this.factoryBeanObjectCache.get(beanName);    return (object != NULL_OBJECT ? object : null);}

可知缓存是存在factoryBeanObjectCache这个对象中:

/** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);

2)如果缓存中不存在,就通过FactoryBean.getObject();方法获取 Object

(2)如果sharedInstance 不是一个FactoryBean,那么就直接返回这个beanInstance。

(3)createBean(beanName, mbd, args);

如果说getBean()是依赖注入的起点,那么createBean()便是最核心的实现部分。这个过程中,Bean对象会依据BeanDefinition定义要求生成。具体的实现在AbstractAutowireCapableBeanFactory中,流程图如下:

依赖注入过程

下面看看核心的源码:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {    //........    //........    Object beanInstance = doCreateBean(beanName, mbdToUse, args);    if (logger.isDebugEnabled()) {        logger.debug("Finished creating instance of bean '" + beanName + "'");    }    return beanInstance;}

其实最核心的就是调用了 doCreateBean(beanName, mbdToUse, args); 方法来创建生成 Bean实例。

下面看看 doCreateBean(beanName, mbdToUse, args);

主要功能是:创建指定的bean;

方法的具体源码实现:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)            throws BeanCreationException {    // 这个BeanWrapper是用来持有创建出来的Bean对象的。    BeanWrapper instanceWrapper = null;    // 如果是单例的bean,就先把缓存中的同名bean清除    if (mbd.isSingleton()) {        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);    }    // 这里就是创建bean的地方, 由createBeanInstance来完成。    if (instanceWrapper == null) {        instanceWrapper = createBeanInstance(beanName, mbd, args);    }    //.........    // 这里是对bean的初始化,依赖注入往往发生在这里,这个exposedObject在初始化处理完以后会返回作为依赖注入完成后的bean。    Object exposedObject = bean;    try {        populateBean(beanName, mbd, instanceWrapper);        if (exposedObject != null) {            exposedObject = initializeBean(beanName, exposedObject, mbd);        }    }    catch (Throwable ex) {        //.......    }    //.......    // Register bean as disposable.    try {        registerDisposableBeanIfNecessary(beanName, bean, mbd);    }    catch (BeanDefinitionValidationException ex) {        throw new BeanCreationException(                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);    }    return exposedObject;}

上面函数中与依赖注入紧密联系的就是下面这两个:

createBeanInstance(beanName, mbd, args);

populateBean(beanName, mbd, instanceWrapper);

createBeanInstance生成了Bean所包含的Java对象,

(4)createBeanInstance(beanName, mbd, args);

根据JavaDoc, 这个方法根据指定的bean创建一个实例。实例的生成策略有很多种: 工厂方法,容器的autowiring生成,或则是简单的instantiation。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {    // 确认类可被实例化    Class<?> beanClass = resolveBeanClass(mbd, beanName);    //使用工厂方法对bean进行实例化    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);        }    }    // 使用构造函数进行实例化    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);    if (ctors != null ||            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {        return autowireConstructor(beanName, mbd, ctors, args);    }    // 使用无参构造函数进行实例化    return instantiateBean(beanName, mbd);}

(5)createBeanInstance(beanName, mbd, args);

前面已经分析了是实例化 Bean对象的整个过程,那么实例化bean 之后,怎么把这些bean的依赖关系设置好,完成整个依赖注入的过程。

这个过程涉及到各种bean对象的属性的处理过程(依赖关系的处理过程),这些依赖关系处理的依据是根据已解析得到的BeanDefinition。详细了解这个过程,就必须回到populateBean()方法,这个方法在AbstractAutowireCapableBeanFactory里实现.

(6)populateBean(beanName, mbd, bw);

populate的意思就是填充的意思,也就是向bean中填充依赖关系的各种属性bean。

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {    // 在这里取得在BeanDefinition中设置的property值,这些property来自对BeanDefinition的解析;    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.    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;    }    //开始进行依赖注入过程,先处理autowire的注入    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);        // 这里autowire注入处理根据Bean的name来处理        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {            autowireByName(beanName, mbd, bw, newPvs);        }        // // 这里autowire注入处理根据Bean的 type 来处理        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, mbd.allowCaching);        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) {            checkDependencies(beanName, mbd, filteredPds, pvs);        }    }    // 对属性进行注入    applyPropertyValues(beanName, mbd, bw, pvs);}

上面的populateBean()函数中,最后对属性的注入过程也就是在最后一行的函数中:

applyPropertyValues(beanName, mbd, bw, pvs);

具体的源码如下:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {    if (pvs == null || pvs.isEmpty()) {        return;    }    MutablePropertyValues mpvs = null;    List<PropertyValue> original;    if (System.getSecurityManager() != null) {        if (bw instanceof BeanWrapperImpl) {            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());        }    }    if (pvs instanceof MutablePropertyValues) {        mpvs = (MutablePropertyValues) pvs;        if (mpvs.isConverted()) {            // Shortcut: use the pre-converted values as-is.            try {                bw.setPropertyValues(mpvs);                return;            }            catch (BeansException ex) {                throw new BeanCreationException(                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);            }        }        original = mpvs.getPropertyValueList();    }    else {        original = Arrays.asList(pvs.getPropertyValues());    }    TypeConverter converter = getCustomTypeConverter();    if (converter == null) {        converter = bw;    }    //对BeanDefinition的解析就是在 valueResolver 这个对象里面完成的。    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);    // 这里为解析值拷贝了一个副本,副本数据被注入到bean中。    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();            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();    }    // Set our (possibly massaged) deep copy.    try {        // 这里是依赖注入发生的地方,会在BeanWrapperImpl中实现        bw.setPropertyValues(new MutablePropertyValues(deepCopy));    }    catch (BeansException ex) {        throw new BeanCreationException(                mbd.getResourceDescription(), beanName, "Error setting property values", ex);    }}

上面对BeanDefinition的解析是通过BeanDefinitionResolver来实现的,在BeanDefinitionResolver的解析过程是多个函数对不同类型数据解析实现的。

所以总的来说就是BeanDefinitionResolver解析BeanDefinition, 然后
BeanWrapper.setPropertyValues(); 来实现真正将bean对象设置到别的依赖的bean属性中去。

BeanDefinitionResolver

这个类有核心的如下方法:

// 对属性的解析基本都会调用这个函数,这个方法包含了对所有注入类型的处理public Object resolveValueIfNecessary(Object argName, Object value);// 解析内部的beanprivate Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd)private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType)private List<?> resolveManagedList(Object argName, List<?> ml)private Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm)private Set<?> resolveManagedSet(Object argName, Set<?> ms)// 解析引用类型;private Object resolveReference(Object argName, RuntimeBeanReference ref)

上面对各个类型的具体的解析过程就暂时不分析了。当解析过程结束后,也就是为依赖注入准备好了条件,之后才是把真正的Bean对象设置到他所依赖的另一个Bean的属性中去,其中处理的属性是各种各样的。 具体的实现是在 BeanWrapper.setPropertyValues中实现。具体的实现在BeanWrapper接口的子类BeanWrapperImpl中实现的。

IOC容器的高级特性

1 0
原创粉丝点击