IoC(Inversion of Control),即控制反转, 也可简单说为依赖注入(DI),旨在将对象间的依赖关系交由 外部环境去处理, 而不是由对象自己去获取,这将大大提升开发效率和降低程序复杂度,在Spring中,这个外部环境就是Spring IoC容器, 也是Spring生态的核心基础,除了Spring的IoC实现外, 其他还有诸如Guice这样的IoC实现, 本文将对Spring的IoC实现进行探讨一番。
Spring中IoC容器(Spring Bean容器)的表现形式比较常见的是BeanFactory和ApplicationContext, 而BeanFactory作为最基础的容器抽象,其规范了一个最基本的IoC容器应该具备的功能:
public interface BeanFactory {
/**
* 用于区别普通Bean和FactoryBean的前缀符号,
* 比如有一个叫myJndiObject的FactoryBean,
* 那么需要通过&myJndiObjec将返回该Factory
*/
String FACTORY_BEAN_PREFIX = "&";
/**
* 根据名称获取Bean
*/
Object getBean(String name) throws BeansException;
/**
* 根据名称获取Bean,并作类型检查
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
/**
* 获取指定类型的Bean
*/
<T> T getBean(Class<T> requiredType) throws BeansException;
/**
* 根据名称获取Bean,若Bean为Prototype类型,使用args作为构造参数
*/
Object getBean(String name, Object... args) throws BeansException;
/**
* 容器中是否包含名称或别名为name的Bean
*/
boolean containsBean(String name);
/**
* 容器中名称或别名为name的Bean是否为单例
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
/**
* 容器中名称或别名为name的Bean是否为原型
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
/**
* 判断名称或别名为name的Bean的类型是否为targetType
*/
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
/**
* 获取名称或别名为name的Bean的类型
*/
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
/**
* 获取名称为name的Bean的所有别名,若name为别名,数组第一个元素为Bean原始名称
*/
String[] getAliases(String name);
}
可以看到BeanFactory中仅定义了如何获取Bean的功能, 但一个Bean容器至少需要具备初始化Bean,创建Bean,装载Bean,注入Bean等基础功能, 这些功能分别在其他接口中进行了扩展,可从BeanFacotry的继承树中可知:
HierarchicalBeanFactory定义了Bean容器之间的父子关系:
/**
* 具有层级关系的Bean容器
*/
public interface HierarchicalBeanFactory extends BeanFactory {
/**
* 获取父级Bean容器或null
*/
BeanFactory getParentBeanFactory();
/**
* 当前Bean容器是否包含名称为name的Bean(不会在父级容器中查询)
*/
boolean containsLocalBean(String name);
}
ListableBeanFactory丰富了获取Bean的功能,如获取多个Bean:
/**
* 具有获取多个Bean的Bean容器<br>
*/
public interface ListableBeanFactory extends BeanFactory {
/**
* 是否包含名称为beanName的BeanDefinition
* @param beanName Bean名称
*/
boolean containsBeanDefinition(String beanName);
/**
* 获取BeanDefinition数量
*/
int getBeanDefinitionCount();
/**
* 获取该Bean容器中内的所有Bean名称
*/
String[] getBeanDefinitionNames();
/**
* 获取指定类型(包括子类)的Bean名称列表
* @param type 指定类型或接口
*/
String[] getBeanNamesForType(Class<?> type);
/**
* 获取指定类型(包括子类)的Bean名称列表
* @param type 指定类型或接口
* @param includeNonSingletons 是否包含非单例的Bean
* @param allowEagerInit 是否初始化懒初始化的单例Bean
*/
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
/**
* 获取指定类型(包括子类)的Bean Map信息(包括其他方式注册的单例Bean)
* @param type 指定类型或接口
*/
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
/**
* 获取指定类型(包括子类)的Bean Map信息(包括其他方式注册的单例Bean)
* @param type 指定类型或接口
* @param includeNonSingletons 是否包含非单例的Bean
* @param allowEagerInit 是否初始化懒初始化的单例Bean
*/
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
/**
* 获取具有指定注解的Bean Map信息
* @param annotationType 注解类型
*/
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException;
/**
* 获取指定Bean的某个注解信息
* @param beanName bean名称
* @param annotationType 注解类型
*/
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
}
AutowireCapableBeanFactory定义了自动装配Bean的功能:
/**
* 具有自动装配Bean的Bean容器
*/
public interface AutowireCapableBeanFactory extends BeanFactory {
/**
* 非自动装配
*/
int AUTOWIRE_NO = 0;
/**
* 通过名称自动装配
*/
int AUTOWIRE_BY_NAME = 1;
/**
* 通过类型自动装配
*/
int AUTOWIRE_BY_TYPE = 2;
/**
* 通过构造器自动装配
*/
int AUTOWIRE_CONSTRUCTOR = 3;
//---------------------------
// 创建和设置外部bean实例的方法:
//---------------------------
/**
* 完全创建一个Bean实例, 包括所有的BeanPostProcessor<br>
* {@link 并不影响按名字或类型装配的属性}
* @param beanClass Bean类型
*/
<T> T createBean(Class<T> beanClass) throws BeansException;
/**
* 装配一个Bean实例(初始化回调或post-processing处理),<br>
* 用于对新实例或反序列化实例,(重新)设置带注解的字段和方法。<br>
* {@link 并不影响按名字或类型装配的属性}
* @param existingBean 存在的bean实例
*/
void autowireBean(Object existingBean) throws BeansException;
/**
* 配置Bean实例
* (包括自动装配bean属性,设置属性值,设置工厂回调,如setBeanName,setBeanFactory,及Bean初始化后的post processors)
* @param existingBean 存在的Bean实例
* @param beanName bean名称
*/
Object configureBean(Object existingBean, String beanName) throws BeansException;
/**
* 解析bean的依赖信息
* @param descriptor 依赖描述对象
* @param beanName bean名称
*/
Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException;
//---------------------------
// 细粒度控制bean生命周期的方法:
//---------------------------
/**
* 完全创建一个Bean实例, 包括所有的BeanPostProcessor<br>
* @param beanClass bean类型
* @param autowireMode 使用名称或类型装配模式
* @param dependencyCheck 是否执行依赖检查
*/
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
/**
* 装配一个bean实例
* @param beanClass bean类型
* @param autowireMode 使用名称或类型装配模式
* @param dependencyCheck 是否执行依赖检查
*/
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
/**
* 装配bean实例的属性
* @param existingBean 存在的bean实例
* @param autowireMode 使用名称或类型装配模式
* @param dependencyCheck 是否执行依赖检查
*/
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
/**
* 将名称为beanName的BeanDefinition的属性值赋给existingBean
* @param existingBean bean实例
* @param beanName BeanDefinition名称
*/
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
/**
* 初始化Bean
* @param existingBean 存在的bean实例
* @param beanName bean名称
*/
Object initializeBean(Object existingBean, String beanName) throws BeansException;
/**
* 调用bean实例的postProcessBeforeInitialization方法
* @param existingBean 存在的bean实例
* @param beanName bean名称
*/
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
/**
* 调用bean实例的postProcessAfterInitialization方法
* @param existingBean 存在的bean实例
* @param beanName bean名称
*/
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
/**
* 解析bean的依赖信息
* @param descriptor 依赖描述信息
* @param beanName bean名称
* @param autowiredBeanNames 自动装配的bean名称集
* @param typeConverter 类型转换器
*/
Object resolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}
ConfigurableBeanFactory定义了一些配置Bean容器的功能:
/**
* 扩展一些配置Bean容器的功能
*/
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
/**
* 单例bean
*/
String SCOPE_SINGLETON = "singleton";
/**
* 原型bean
*/
String SCOPE_PROTOTYPE = "prototype";
/**
* 设置父容器
*/
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
/**
* 设置Bean类加载器
*/
void setBeanClassLoader(ClassLoader beanClassLoader);
ClassLoader getBeanClassLoader();
/**
* 设置临时类加载器
*/
void setTempClassLoader(ClassLoader tempClassLoader);
ClassLoader getTempClassLoader();
/**
* 设置是否缓存Bean元数据
*/
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();
/**
* 设置Bean表达式解析器
*/
void setBeanExpressionResolver(BeanExpressionResolver resolver);
BeanExpressionResolver getBeanExpressionResolver();
/**
* 设置类型转换服务
*/
void setConversionService(ConversionService conversionService);
ConversionService getConversionService();
...
}
ApplicationContext作为最常用的Bean容器,比如WebApplicationContext,ClassPathXmlApplicationContext等, 其对最基础的BeanFactory进行了一些扩展,如EnvironmentCapable(容器运行时环境,有了它就能在Spring使用中区分开发,测试,生产等环境),MessageSource(消息参数化和国际化功能),ApplicationEventPublisher(应用事件发布功能),ResourcePatternResolver(资源解析功能),似乎ApplicationContext缺少了一些功能,如AutowireCapableBeanFactory(自动装配功能),但其实ApplicationContext通过内部包装了一个AutowireCapableBeanFactory来重用基础Bean容器的功能:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
/**
* 应用ID
*/
String getId();
/**
* 应用名称,默认""
*/
String getApplicationName();
/**
* 应用易读的名称
*/
String getDisplayName();
/**
* 容器第一次加载的时间戳
*/
long getStartupDate();
/**
* 父容器
*/
ApplicationContext getParent();
/**
* 包装一个可自动装配的Bean容器
*/
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
ApplicationContext作为开发人员最常用的Bean容器,Spring已经为我们提供很多现成的实现可用, 从ApplicationContext的继承树中可以看出:
其中有我们非常熟悉的ClassPathXmlApplicationContext和XmlWebApplicationContext。
既然有了Bean容器,那么Bean是什么呢?在Spring中,Bean的定义抽象为BeanDefinition:
/**
* 基础Bean定义
*/
public interface BeanDefinition {
/**
* 获取该Bean的父级Bean名称
*/
String getParentName();
void setParentName(String parentName);
/**
* 获取Bean的类名称(并不一定是该Bean实际的类名称,比如子Bean重写或继承父级Bean的类名称)
*/
String getBeanClassName();
void setBeanClassName(String beanClassName);
/**
* 获取FactoryBean名称
*/
String getFactoryBeanName();
void setFactoryBeanName(String factoryBeanName);
/**
* 获取构建该Bean的工厂方法名称,将使用构造器参数调用该工厂方法
*/
String getFactoryMethodName();
void setFactoryMethodName(String factoryMethodName);
/**
* 获取Bean的元类型,SINGLETON或PROTOTYPE
*/
String getScope();
void setScope(String scope);
/**
* 该Bean是否懒加载,即不在Spring容器启动时初始化,只针对SINGLETON类型的Bean
*/
boolean isLazyInit();
void setLazyInit(boolean lazyInit);
/**
* 该Bean所依赖的其他Bean名称列表
*/
String[] getDependsOn();
void setDependsOn(String[] dependsOn);
/**
* 该Bean是否会注入到其他Bean中
*/
boolean isAutowireCandidate();
void setAutowireCandidate(boolean autowireCandidate);
/**
* 该Bean是否注入到了多个Bean中
*/
boolean isPrimary();
void setPrimary(boolean primary);
/**
* 是否为SINGLETON元类型
*/
boolean isSingleton();
/**
* 是否为PROTOTYPE元类型
*/
boolean isPrototype();
/**
* 该Bean是否是"抽象的", 就是不能实例化
*/
boolean isAbstract();
/**
* 该Bean的角色:
* 0: 应用级别的Bean,如用户定义的Bean
* 1: 支持级别的Bean,比如一些配置Bean
* 2: 基础级别Bean,与用户无关,
*/
int getRole();
/**
* Bean描述
*/
String getDescription();
/**
* 该Bean来自的上下文描述,用于错误信息记录
*/
String getResourceDescription();
/**
* 递归获取该BeanDefinition包装的内部BeanDefinition
*/
BeanDefinition getOriginatingBeanDefinition();
}
在构建Bean容器时,我们会传入对应的配置文件路径,如:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-context.xml");
对于传入的文件等资源信息,Spring内部会抽象为Resource接口:
public interface Resource extends InputStreamSource {
/**
* Return whether this resource actually exists in physical form.
* <p>This method performs a definitive existence check, whereas the
* existence of a {@code Resource} handle only guarantees a
* valid descriptor handle.
*/
boolean exists();
/**
* Return whether the contents of this resource can be read,
* e.g. via {@link #getInputStream()} or {@link #getFile()}.
* <p>Will be {@code true} for typical resource descriptors;
* note that actual content reading may still fail when attempted.
* However, a value of {@code false} is a definitive indication
* that the resource content cannot be read.
* @see #getInputStream()
*/
boolean isReadable();
/**
* Return whether this resource represents a handle with an open
* stream. If true, the InputStream cannot be read multiple times,
* and must be read and closed to avoid resource leaks.
* <p>Will be {@code false} for typical resource descriptors.
*/
boolean isOpen();
/**
* Return a URL handle for this resource.
* @throws IOException if the resource cannot be resolved as URL,
* i.e. if the resource is not available as descriptor
*/
URL getURL() throws IOException;
/**
* Return a URI handle for this resource.
* @throws IOException if the resource cannot be resolved as URI,
* i.e. if the resource is not available as descriptor
*/
URI getURI() throws IOException;
/**
* Return a File handle for this resource.
* @throws IOException if the resource cannot be resolved as absolute
* file path, i.e. if the resource is not available in a file system
*/
File getFile() throws IOException;
/**
* Determine the content length for this resource.
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/
long contentLength() throws IOException;
/**
* Determine the last-modified timestamp for this resource.
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/
long lastModified() throws IOException;
/**
* Create a resource relative to this resource.
* @param relativePath the relative path (relative to this resource)
* @return the resource handle for the relative resource
* @throws IOException if the relative resource cannot be determined
*/
Resource createRelative(String relativePath) throws IOException;
/**
* Determine a filename for this resource, i.e. typically the last
* part of the path: for example, "myfile.txt".
* <p>Returns {@code null} if this type of resource does not
* have a filename.
*/
String getFilename();
/**
* Return a description for this resource,
* to be used for error output when working with the resource.
* <p>Implementations are also encouraged to return this value
* from their {@code toString} method.
* @see Object#toString()
*/
String getDescription();
}
之前大概了解了Spring中的IoC容器体系结构,接下来将讲述IoC容器是如何实现,及一步步建立起来。可以从比较熟悉的一个IoC容器实现ClassPathXmlApplicationContext说起,开发应用时,ClassPathXmlApplicationContext基本用法:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-context.xml");
context.start();
上面2行代码,就已经构建了一个完整的IoC容器,现在需要逐步分析构建的各个主要过程。可以看下ClassPathXmlApplicationContext的继承树,来分析IoC功能是如何一步步建立起来的:
ClassPathXmlApplicationContext的构建从其构造函数中的refresh()开始,我们也可以通过该方法,在运行时对IoC容器进行重新加载:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
// configLocations为我们配置的xml文件,可以以逗号,分号等为分隔符
setConfigLocations(configLocations);
if (refresh) {
// 刷新容器
refresh();
}
}
对于configLocations,其中的文件路径是支持占位属性的, 如路径可以像这样classpath:${property_name}-context.xml,这其实又为我们提供了一种配置多环境的方式,refresh()方法涵盖了整个IoC容器初始化的过程:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 初始化前作一些准备操作,如记录启动时间,处理占位属性源,验证必要的上下文属性等
prepareRefresh();
// 交由子类去初始化容器
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 配置容器的标准上下文特性,如类加载器,回调,
prepareBeanFactory(beanFactory);
try {
// 允许子类对容器进行处理,此时BeanDefinition已经加载完毕,但没有Bean实例生成
postProcessBeanFactory(beanFactory);
// 调用注册的BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 实例化并调用BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 初始化信息源
initMessageSource();
// 初始化应用事件广播器
initApplicationEventMulticaster();
// 交由子类实例化一些特殊的Bean
onRefresh();
// 注册应用监听器
registerListeners();
// 实例化所有非lazy-ini的单例Bean
finishBeanFactoryInitialization(beanFactory);
// 发布事件
finishRefresh();
} catch (BeansException ex) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
// 销毁注册的单例bean
destroyBeans();
// 重置
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
整个refresh过程的调用链为:
可以看到ApplicationContext内部使用DefaultListableBeanFactory作为Bean容器实现,使用XmlBeanDefinitionReader读取Bean资源配置文件,使用BeanDefinitionParserDelegate对具体的Bean元素进行解析。
AbstractRefreshableApplicationContext.refreshBeanFactory():
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
// 若内部已经有BeanFactory,则先销毁
destroyBeans();
closeBeanFactory();
}
try {
// 实例化默认的Bean容器实现
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 定制一些BeanFactory属性,如是否允许BeanDefinition覆盖,循环引用等
customizeBeanFactory(beanFactory);
// 开始加载BeanDefinition
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 创建XmlBeanDefinitionReader实例:
// 1. 初始化ResourceLoader,默认为PathMatchingResourcePatternResolver
// 2. 初始化Environment,默认为StandardEnvironment
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 重新设置Environment和ResourceLoader,
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 初始化BeanDefinitionReader
initBeanDefinitionReader(beanDefinitionReader);
// 开始加载BeanDefinition
loadBeanDefinitions(beanDefinitionReader);
}
再到XML文档读取器DefaultBeanDefinitionDocumentReader:
protected void doRegisterBeanDefinitions(Element root) {
// 获取Spring环境变量profile
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getEnvironment().acceptsProfiles(specifiedProfiles)) {
return;
}
}
// 实例化BeanDefinitionParserDelegate
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(this.readerContext, root, parent);
// 交由子类XML预处理
preProcessXml(root);
// 从root节点开始解析BeanDefinition
parseBeanDefinitions(root, this.delegate);
// 交由子类XML后置处理
postProcessXml(root);
this.delegate = parent;
}
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
// 解析默认元素
parseDefaultElement(ele, delegate);
} else {
// 解析定制的元素
delegate.parseCustomElement(ele);
}
}
}
} else {
// 解析定制的元素
delegate.parseCustomElement(root);
}
}
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
// import元素,会重新重另一个resource文件中解析
importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
// alia元素
processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
// bean元素
processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// 递归解析beans元素
doRegisterBeanDefinitions(ele);
}
}
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 将bean元素解析为BeanDefinitionHolder对象
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 注册最终装饰的bean实例及别名信息
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 发送注册事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
// BeanDefinitionParserDelegate#parseBeanDefinitionElement
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
// 实例化BeanDefinition,使用GenericBeanDefinition实现
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 解析bean元素属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// 设置description元素
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 解析meta元素
parseMetaElements(ele, bd);
// 解析lookup-method元素
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析replaced-method元素
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析constructor-arg元素
parseConstructorArgElements(ele, bd);
// 解析property元素
parsePropertyElements(ele, bd);
// 解析qualifier元素
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
上面就是一个冗长的bean元素解析流程,完全解析后,回到BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());进行bean注册,最终将放到DefaultListableBeanFactory的beanDefinitionMap属性中:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
synchronized (this.beanDefinitionMap) {
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
// 遇到重复的beanName,需要设置allowBeanDefinitionOverriding为true
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
}
else {
// 记录bean注册顺序
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
当所有bean完成注册后,IoC容器还需要完成bean的依赖注入配置,对于lazyInit为true的bean,会在向容器getBean 时,实例化bean及完成依赖注入,整个依赖注入过程大概如:
从DefaultListableBeanFactory的getBean方法开始:
public <T> T getBean(Class<T> requiredType) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
// 通过类型获取bean名称
String[] beanNames = getBeanNamesForType(requiredType);
if (beanNames.length > 1) {
ArrayList<String> autowireCandidates = new ArrayList<String>();
for (String beanName : beanNames) {
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (autowireCandidates.size() > 0) {
beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
}
}
if (beanNames.length == 1) {
// 获取bean实例
return getBean(beanNames[0], requiredType);
} else if (beanNames.length > 1) {
// 当一个类型对应了多个beanName时,会优先考虑primary为true的bean
T primaryBean = null;
for (String beanName : beanNames) {
T beanInstance = getBean(beanName, requiredType);
if (isPrimary(beanName, beanInstance)) {
if (primaryBean != null) {
throw new NoUniqueBeanDefinitionException(requiredType, beanNames.length,
"more than one 'primary' bean found of required type: " + Arrays.asList(beanNames));
}
primaryBean = beanInstance;
}
}
if (primaryBean != null) {
return primaryBean;
}
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
} else if (getParentBeanFactory() != null) {
// 从父容器中查询bean
return getParentBeanFactory().getBean(requiredType);
} else {
throw new NoSuchBeanDefinitionException(requiredType);
}
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 得到规范的bean名称, 如将FactoryBean中的&去掉和bean别名转换
final String beanName = transformedBeanName(name);
Object bean;
// 优先检查单例bean,有必要就创建
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
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 + "'");
}
}
// FactoryBean相关处理
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 当前bean是prototype类型,且正在创建中
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查bean是否存在于父级Bean容器中
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// 标记bean为创建了
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 注册该bean所依赖的bean集合
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
// 单例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
// 创建bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 原型bean
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
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;
}
}
// Check if required type matches the type of the actual bean instance.
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;
}
再看AbstractAutowireCapableBeanFactory.createBean:
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
// 确保beanClass已经解析
resolveBeanClass(mbd, beanName);
try {
// 准备方法重写
mbd.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 若bean配置了PostProcessors,则返回其代理实例
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 移除缓存中factoryBean实例
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建bean实例
// 1. 若没有方法重写,使用SimpleInstantiationStrategy,构造器newInstance实例化bean
// 2. 若有方法重写,使用CglibSubclassingInstantiationStrategy,Enhancer.create实例化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// bean实例
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
// bean类型
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// 允许PostProcessors修改BeanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
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");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
Object exposedObject = bean;
try {
// 填充bean实例,触发依赖注入
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 执行bean的PostProprocessors,init方法,和一些接口回调,如InitializingBean.
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) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
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 {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// bean的属性集
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;
}
}
// 在bean属性设置前,InstantiationAwareBeanPostProcessors可以修改bean的状态
// 比如常用的Autowired注解,也就是一个BeanPostProcessor,即AutowiredAnnotationBeanPostProcessor
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)) {
// postProcessAfterInstantiation返回false,表示跳过属性设置,通常应该返回true
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
// 先处理autowired依赖注入,bean的配置中可以是byName or byType
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 通过名字装配属性
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 通过类型装配属性
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);
}
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;
}
// bean实例解析器
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();
// 从PropertyValue中解析出bean的值对象,比较典型的如RuntimeBeanReference,将解析出对应的bean对象
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();
}
try {
// 设置属性
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
} catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
以上就基本了解了IoC容器的依赖注入过程,基本思路虽然简单,将之前从配置文件中加载好的BeanDefinition进行逐一装配, 但其中涉及的思路和设计细节众多,完全弄透还是很需要时间来调试跟踪的。
对于平时使用Spring时,对于预实例化的bean,该动作会在refresh方法中的finishBeanFactoryInitialization中完成,内部其实也是一个getBean的过程。
在平常Spring使用中,通常并不会手动去配置bean之间的依赖关系,而是通过一些注解就能简单清晰地维护bean之间的依赖关系,这是如何做到的呢?首先我们需要开启spring的注解配置功能,需要如下配置如:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 开启注解配置 -->
<context:annotation-config />
<!-- 注解配置扫描包路径 -->
<context:component-scan base-package="service" />
...
</beans>
这需要先从xml命名空间(namespace)解析开始,该解析过程在DefaultBeanDefinitionDocumentReader.parseBeanDefinitions()中:
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// 是否为默认的命名空间,即http://www.springframework.org/schema/beans
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
// 若是http://www.springframework.org/schema/beans命名空间下的元素
parseDefaultElement(ele, delegate);
} else {
// 若是其他命名空间下的元素,如xmlns:context="http://www.springframework.org/schema/context
delegate.parseCustomElement(ele);
}
}
}
} else {
// 若是其他命名空间下的元素,如xmlns:context="http://www.springframework.org/schema/context
delegate.parseCustomElement(root);
}
}
// BeanDefinitionParserDelegate.parseCustomElement
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
// 解析namespace
String namespaceUri = getNamespaceURI(ele);
// 解析对应的NamespaceHandler,并作init初始化
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 交由对应的handler去解析元素
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
而对于NamespaceHandler,会在XmlBeanDefinitionReader中初始化,并通过readerContext传递给BeanDefinitionParserDelegate:
// 创建readerContext
protected XmlReaderContext createReaderContext(Resource resource) {
if (this.namespaceHandlerResolver == null) {
this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
}
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, this.namespaceHandlerResolver);
}
// 创建NamespaceHandlerResolver
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());
}
public DefaultNamespaceHandlerResolver(ClassLoader classLoader) {
// 默认为加载META/spring.handlers,包括jar包内META/spring.handlers
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
在Spring源代码中,比如spring-beans和spring-context中配置的handlers:
// spring-beans/META/spring.handlers
http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
// spring-context/META/spring.handlers
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
因此context命名空间对应着ContextNamespaceHandler:
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
}
因此最终annotation-config将由AnnotationConfigBeanDefinitionParser来解析:
public BeanDefinition parse(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
// 获取与当前元素相关的BeanPostProcessors,并且注册到IoC容器
// 这时就会实例化一些比较熟悉的注解处理器:
// 1. ConfigurationClassPostProcessor -> @Configuration
// 2. AutowiredAnnotationBeanPostProcessor -> @Autowired @Value @Inject
// 3. RequiredAnnotationBeanPostProcessor -> @Required
// 4. CommonAnnotationBeanPostProcessor -> JSR-250: @Resource @PostConstruct @PreDestroy @WebServiceRef @EJB, ...
// 5. ...
Set<BeanDefinitionHolder> processorDefinitions =
AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);
// 保存context:annotation-config复合组件: 复合组件可以多个嵌套的ComponentDefinition组件
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
parserContext.pushContainingComponent(compDefinition);
// 将bean包装成bean组件,并注册.
for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
parserContext.registerComponent(new BeanComponentDefinition(processorDefinition));
}
// 注册整个复合组件
parserContext.popAndRegisterContainingComponent();
return null;
}
同理当解析到component-scan,则会调用ComponentScanBeanDefinitionParser:
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 解析扫描包
String[] basePackages = StringUtils.tokenizeToStringArray(element.getAttribute(BASE_PACKAGE_ATTRIBUTE),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// 生成类路径Bean扫描器,主要扫描常用的注解
// 1. 本地注解: @Component,@Repository,@Service, @Controller
// 2. Java EE 6's: @ManagedBean
// 3. JSR-330's: @Named
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
// 扫描包下的Bean并注册到IoC容器中, 扫面到的Bean都封装为ScannedGenericBeanDefinition对象
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
// 注册组件component-scan复合组件
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
// 实例化ClassPathBeanDefinitionScanner
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
XmlReaderContext readerContext = parserContext.getReaderContext();
// 是否使用默认Filter
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
}
// 实例化ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters);
scanner.setResourceLoader(readerContext.getResourceLoader());
scanner.setEnvironment(parserContext.getDelegate().getEnvironment());
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
}
try {
// 设置bean名称生成器
// 若注解中没有指定bean名称,则使用BeanNameGenerator,默认是类简单名称(首字母小写)
parseBeanNameGenerator(element, scanner);
} catch (Exception ex) {
readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
}
try {
// 设置@Scope注解的解析器
parseScope(element, scanner);
} catch (Exception ex) {
readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
}
// 设置includeFilter和excludeFilter
parseTypeFilters(element, scanner, readerContext, parserContext);
return scanner;
}
// ClassPathBeanDefinitionScanner.doScan
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
for (String basePackage : basePackages) {
// 从类路径扫描有注解的BeanDefinition
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 解析bean的@Scope注解信息,没设置默认singleton
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 生成bean名称
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 解析一些通用注解,如@Primary,@Lazy,@DependsOn,@Role,并设置对应的BeanDefinition属性
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查当前Bean是否冲突
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 应用ScopedProxy
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注册BeanDefinition到IoC容器
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
try {
// 解析查询路径: com.xxx -> classpath*:com/xxx/**/*.class
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + "/" + this.resourcePattern;
// 解析出packageSearchPath下所有的class文件资源
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
// 将classw文件资源封装为MetadataReader对象
// MetadataReader通过ASM API读取class信息,包括类信息ClassMetadata和注解信息AnnotationMetadata
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
// 排除exclude-filter的class
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
} else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
} else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
} else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
通过component-scan(组件扫描)后,注解的类都被加载到IoC容器中, 除了BeanDefinition外,还有上面提到的注解处理器, 这些BeanPostProcessor也会如之前所说,在Bean实例化时调用:
// AbstractAutowireCapableBeanFactory.populateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
...
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;
}
}
}
}
...
}
...
}
比如针对@Autowried注解的处理器AutowiredAnnotationBeanPostProcessor:
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
// 查询bean类型的注入元数据,如带@Autoried注解的字段
// 但这已经在AbstractAutowireCapableBeanFactory.doCreateBean() -> applyMergedBeanDefinitionPostProcessors()中缓存了这些元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 注入Bean属性
metadata.inject(bean, beanName, pvs);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
// 以beanName为cache key
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 构建类的注入元数据
metadata = buildAutowiringMetadata(clazz);
// 放入缓存
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
do {
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
// 获取注解字段
for (Field field : targetClass.getDeclaredFields()) {
Annotation ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
// 获取静态字段的@Autowired
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
continue;
}
// 是否为required
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
}
// 获取注解方法
for (Method method : targetClass.getDeclaredMethods()) {
Annotation ann = null;
// 获取bridge方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
// 获取Autowired方法
ann = findAutowiredAnnotation(bridgedMethod);
}
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
// 忽略静态方法
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
continue;
}
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
}
// 为何这里不continue?
}
// 是否为required
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
elements.addAll(0, currElements);
// 递归父类
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
// InjectionMetadata.inject
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
// 执行元素inject操作,包含字段(AutowiredFieldElement)或方法(AutowiredMethodElement)
element.inject(target, beanName, pvs);
}
}
}
// 字段注入: AutowiredFieldElement.inject
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
try {
Object value;
if (this.cached) {
// 解析缓存的方法参数或字段值
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
} else {
// 封装依赖描述对象
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
// 解析依赖的bean
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
// 注册依赖的bean
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)) {
// 类型匹配
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
// 缓存字段值
this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);
}
}
}
} else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
// 设置@Autowired字段
field.set(bean, value);
}
} catch (Throwable ex) {
throw new BeanCreationException("Could not autowire field: " + field, ex);
}
}
// 方法注入: AutowiredFieldElement.inject
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
// 是否跳过
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
try {
Object[] arguments;
if (this.cached) {
// 解析缓存的方法参数
arguments = resolveCachedArguments(beanName);
} else {
Class<?>[] paramTypes = method.getParameterTypes();
arguments = new Object[paramTypes.length];
DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
Set<String> autowiredBeanNames = new LinkedHashSet<String>(paramTypes.length);
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
GenericTypeResolver.resolveParameterType(methodParam, bean.getClass());
// 封装方法参数
descriptors[i] = new DependencyDescriptor(methodParam, this.required);
// 解析参数值
arguments[i] = beanFactory.resolveDependency(
descriptors[i], beanName, autowiredBeanNames, typeConverter);
if (arguments[i] == null && !this.required) {
arguments = null;
break;
}
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
this.cachedMethodArguments = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
// 缓存方法参数
this.cachedMethodArguments[i] = descriptors[i];
}
// 注册依赖的bean
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == paramTypes.length) {
Iterator<String> it = autowiredBeanNames.iterator();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName)) {
if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
// 尝试缓存方法参数为RuntimeBeanReference
this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName);
}
}
}
}
} else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
}
if (arguments != null) {
ReflectionUtils.makeAccessible(method);
// 调用@Autowired方法
method.invoke(bean, arguments);
}
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
} catch (Throwable ex) {
throw new BeanCreationException("Could not autowire method: " + method, ex);
}
}
以上则是依赖注入的基本实现轮廓,读者可以尝试debug各种情况。