【技术分享】-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容器更加高级的一些特性的支持。
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容器的高级特性
- 【技术分享】-Spring的IOC
- Spring IoC(控制反转)【IoC的技术基础】
- spring 框架的一个技术点IOC
- IOC、Spring的IOC
- spring 技术内幕--IOC
- ioc spring技术手册学习
- ioc spring技术手册学习
- Spring Ioc 技术(constructor-arg )
- Spring Ioc 技术(constructor-arg )
- Spring系列(5)---IOC技术.
- jsp spring 技术(二) ----- IOC
- Spring系列(5)---IOC技术.
- spring framework中的IOC技术
- spring技术内幕读书笔记--IOC
- spring中ioc,aop和java代理技术的关系
- spring技术内幕5-IoC容器的依赖注入
- spring技术内幕6-IoC容器的高级特性
- Spring技术内幕笔记 -- IoC容器的实现
- 文章标题
- springmvc详解及demo的搭建
- exynos 4412 时钟配置
- ImportError: Failed to import pydot. You must install pydot and graphviz for `pydotprint` to work.
- mybatis的输入和输出映射
- 【技术分享】-Spring的IOC
- Git 的基本使用
- Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into
- 新建虚拟机安装linux系统(CentOS7)
- 判断网络请求
- 最小生成树-prim
- Android Studio 简单的NDK开发
- nginx
- Exynos4412时钟体系分析