为何重拾
使用了 Spring 多年,但是对其底层的一些实现还是一知半解,一些概念比较模糊;故决定重新拾起,加深对 Spring 的认识。
重拾计划
spring 版本说明
Spring 在经过多年的演进过程中,其功能越来越丰富,组件越来越多;为了避免在阅读源码的过程中深陷泥潭中,决定采用最原始的版本 1.0; 但又不局限于 1.0 版本。
spring ioc
spring aop
spring 事务管理
spring orm 集成
实现分析
Spring 容器启动
在本文中,通过常用的构造
ClassPathXmlApplicationContext
实例来作为对 Spring 实现分析的入口
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
通过调用链追踪,Spring 容器启动核心操作由 AbstractApplicationContext
类中 refresh
方法实现
public void refresh() throws BeansException {
this.startupTime = System.currentTimeMillis();
// tell subclass to refresh the internal bean factory
// 完成 xml 配置文件的解析, 解析 bean 标签生成 BeanDefinition 对象,并注册到 BeanFactory
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// configure the bean factory with context semantics
beanFactory.registerCustomEditor(Resource.class, new ContextResourceEditor(this));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyType(ResourceLoader.class);
beanFactory.ignoreDependencyType(ApplicationContext.class);
postProcessBeanFactory(beanFactory);
// invoke factory processors registered with the context instance
// 获取内置 BeanFactoryPostProcessor 实例,并遍历调用 postProcessBeanFactory 方法
// 对 BeanFactory 进行后置处理
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
if (getBeanDefinitionCount() == 0) {
logger.warn("No beans defined in ApplicationContext [" + getDisplayName() + "]");
}
else {
logger.info(getBeanDefinitionCount() + " beans defined in ApplicationContext [" + getDisplayName() + "]");
}
// invoke factory processors registered as beans in the context
// 从 Bean Definition 集合中查找 BeanFactoryPostProcessor 定义并实例化
// 获取 BeanFactoryPostProcessor 实例,并遍历调用 postProcessBeanFactory 方法
// 对 BeanFactory 进行后置处理
invokeBeanFactoryPostProcessors();
// register bean processor that intercept bean creation
// 从 Bean Definition 集合中查找 BeanPostProcessor 类定义实例化并注册到 BeanFactory 中
registerBeanPostProcessors();
// initialize message source for this context
initMessageSource();
// initialize other special beans in specific context subclasses
onRefresh();
// check for listener beans and register them
refreshListeners();
// instantiate singletons this late to allow them to access the message source
// 对 Bean Definition 中单例且非延迟加载的类型进行实例化
/**
* bean 初始化过程如下:
* 1 : bean 构造初始化
* 2 : bean 属性注入 (通过 bean definition 中的 property , autowire(byType, byName) 实现)
* 3 : bean 若实现 BeanNameAware 接口,调用 setBeanName() 方法
* 4 : bean 若实现 BeanFactoryAware 接口, 调用 setBeanFactory() 方法
* 5 : 遍历调用 BeanFactory 中注册的 BeanPostProcessor 实例的 postProcessorBeforeInitialization() 方法
* 6 : bean 若实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法
* 7 : bean 实例对应的 bean definition 中若定义了 init-method 属性则调用对应的 init 方法
* 8 : 遍历调用 BeanFactory 中注册的 BeanPostProcessor 实例的 postProcessorAfterInitialization() 方法
*/
beanFactory.preInstantiateSingletons();
// last step: publish respective event
publishEvent(new ContextRefreshedEvent(this));
}
从源码中可知,Spring 容器在启动过程中,主要完成以下流程 :
- 通过加载指定的配置文件,完成 Bean Definition 解析并注册到 BeanFactory 实例中
- 通过内置及应用自定义的 BeanFactoryPostProcessor 对 BeanFactory 实例进行后置处理
- 实例化应用自定义的 BeanPostProcessor 并注册到 BeanFactory 实例中
- 实例化 Spring 容器中的 Bean
Spring 容器关闭
public void close() {
logger.info("Closing application context [" + getDisplayName() + "]");
// destroy all cached singletons in this context,
// invoking DisposableBean.destroy and/or "destroy-method"
// 销毁容器中缓存的单例对象实例
// 执行容器中 DisposableBean 的 destroy 方法
getBeanFactory().destroySingletons();
// publish respective event
// 发送 spring 上下文关闭事件
publishEvent(new ContextClosedEvent(this));
}
通过调用链追踪,Spring 会遍历容器中缓存的 bean 实例调用 destroyBean 方法。
protected void destroyBean(String beanName, Object bean) {
logger.debug("Retrieving depending beans for bean '" + beanName + "'");
// 先销毁所有依赖当前 bean 的实例
String[] dependingBeans = getDependingBeanNames(beanName);
if (dependingBeans != null) {
for (int i = 0; i < dependingBeans.length; i++) {
destroySingleton(dependingBeans[i]);
}
}
if (bean instanceof DisposableBean) {
// 如果 bean 实现了 DisposableBean 接口,将会执行 destroy 方法
logger.debug("Calling destroy() on bean with name '" + beanName + "'");
try {
((DisposableBean) bean).destroy();
}
catch (Exception ex) {
logger.error("destroy() on bean with name '" + beanName + "' threw an exception", ex);
}
}
try {
RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
if (bd.getDestroyMethodName() != null) {
// 如果 bean 定义了 destroy-method 属性,将会调用自定义的销毁方法
logger.debug("Calling custom destroy method '" + bd.getDestroyMethodName() +
"' on bean with name '" + beanName + "'");
invokeCustomDestroyMethod(beanName, bean, bd.getDestroyMethodName());
}
}
catch (NoSuchBeanDefinitionException ex) {
// ignore, from manually registered singleton
}
}
下面将针对 Spring Bean 在容器启动过程中的各个环节的实现进行详细说明
Spring Bean 定义解析
通过对 refreshBeanFactory
方法的调用链追踪,可以看到在 DefaultXmlBeanDefinitonParser
类的 registerBeanDefinitions
方法中实现对 Spring Bean 定义的解析及注册。
public void registerBeanDefinitions(BeanDefinitionRegistry beanFactory, ClassLoader beanClassLoader,
Document doc, Resource resource) {
this.beanFactory = beanFactory;
this.beanClassLoader = beanClassLoader;
this.resource = resource;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
this.defaultLazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
logger.debug("Default lazy init '" + this.defaultLazyInit + "'");
this.defaultDependencyCheck = root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE);
logger.debug("Default dependency check '" + this.defaultDependencyCheck + "'");
this.defaultAutowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
logger.debug("Default autowire '" + this.defaultAutowire + "'");
NodeList nl = root.getChildNodes();
int beanDefinitionCounter = 0;
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && BEAN_ELEMENT.equals(node.getNodeName())) {
beanDefinitionCounter++;
loadBeanDefinition((Element) node);
}
}
logger.debug("Found " + beanDefinitionCounter + " <" + BEAN_ELEMENT + "> elements defining beans");
}
protected void loadBeanDefinition(Element ele) {
// 获取 bean 的 id, name 属性
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List aliases = new ArrayList();
if (nameAttr != null && !"".equals(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS, true, true);
aliases.addAll(Arrays.asList(nameArr));
}
if (id == null || "".equals(id) && !aliases.isEmpty()) {
id = (String) aliases.remove(0);
logger.debug("No XML 'id' specified - using '" + id + "' as ID and " + aliases + " as aliases");
}
// 解析 bean 标签, 获取 bean 配置的属性,构造,是否懒加载 作用域
AbstractBeanDefinition beanDefinition = parseBeanDefinition(ele, id);
if (id == null || "".equals(id)) {
if (beanDefinition instanceof RootBeanDefinition) {
id = ((RootBeanDefinition) beanDefinition).getBeanClassName();
logger.debug("Neither XML 'id' nor 'name' specified - using bean class name [" + id + "] as ID");
}
else {
throw new BeanDefinitionStoreException(this.resource, "","Child bean definition has neither 'id' nor 'name'");
}
}
logger.debug("Registering bean definition with id '" + id + "'");
// 将 bean definiton 注册到 beanFactory
this.beanFactory.registerBeanDefinition(id, beanDefinition);
for (Iterator it = aliases.iterator(); it.hasNext();) {
this.beanFactory.registerAlias(id, (String) it.next());
}
}
protected AbstractBeanDefinition parseBeanDefinition(Element ele, String beanName) {
String className = null;
try {
// 获取 class 属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE);
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
if (className == null && parent == null) {
throw new BeanDefinitionStoreException(this.resource, beanName, "Either 'class' or 'parent' is required");
}
AbstractBeanDefinition bd = null;
// 获取属性
MutablePropertyValues pvs = getPropertyValueSubElements(beanName, ele);
if (className != null) {
// 获取构造
ConstructorArgumentValues cargs = getConstructorArgSubElements(beanName, ele);
RootBeanDefinition rbd = null;
if (this.beanClassLoader != null) {
Class clazz = Class.forName(className, true, this.beanClassLoader);
rbd = new RootBeanDefinition(clazz, cargs, pvs);
}
else {
rbd = new RootBeanDefinition(className, cargs, pvs);
}
// 设置 bean dependOn
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
rbd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS, true, true));
}
String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
if (DEFAULT_VALUE.equals(dependencyCheck)) {
dependencyCheck = this.defaultDependencyCheck;
}
rbd.setDependencyCheck(getDependencyCheck(dependencyCheck));
// 设置 bean 自动注册的方式 byType, byName or none
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(autowire)) {
autowire = this.defaultAutowire;
}
rbd.setAutowireMode(getAutowireMode(autowire));
// 设置 bean 的 init-method
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
if (!initMethodName.equals("")) {
rbd.setInitMethodName(initMethodName);
}
// 设置 bean 的 destroy-method
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
if (!destroyMethodName.equals("")) {
rbd.setDestroyMethodName(destroyMethodName);
}
bd = rbd;
}
else {
bd = new ChildBeanDefinition(parent, pvs);
}
// 设置 bean 是否为单例
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)));
}
// 是否懒加载
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
// just apply default to singletons, as lazy-init has no meaning for prototypes
lazyInit = this.defaultLazyInit;
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
bd.setResourceDescription(this.resource.getDescription());
return bd;
}
catch (ClassNotFoundException ex) {
}
catch (NoClassDefFoundError err) {}
}
Spring 容器在将配置文件加载后,会解析 bean 标签并通过其相应的属性配置构造 BeanDefinition 对象,然后将 BeanDefinition 对象注册添加到 BeanFactory 中。
Spring Bean 实例化
public void preInstantiateSingletons() {
if (logger.isInfoEnabled()) {
logger.info("Pre-instantiating singletons in factory [" + this + "]");
}
// 遍历注册的 bean definition
for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
String beanName = (String) it.next();
if (containsBeanDefinition(beanName)) {
RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
// 如果 bean 定义为单例且非延迟加载的
if (bd.isSingleton() && !bd.isLazyInit()) {
// 判断 bean 是否为 FactoryBean
if (FactoryBean.class.isAssignableFrom(bd.getBeanClass())) {
FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
if (factory.isSingleton()) {
getBean(beanName);
}
}
else {
// 若是普通 bean 则调用 getBean
getBean(beanName);
}
}
}
}
}
public Object getBean(String name) throws BeansException {
String beanName = transformedBeanName(name);
// eagerly check singleton cache for manually registered singletons
// 检查单例缓存池中 是否存在 bean 实例,如果有从缓存中获取 bean 实例
Object sharedInstance = this.singletonCache.get(beanName);
if (sharedInstance != null) {
if (logger.isDebugEnabled()) {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
return getObjectForSharedInstance(name, sharedInstance);
}
else {
// check if bean definition exists
RootBeanDefinition mergedBeanDefinition = null;
try {
mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
}
catch (NoSuchBeanDefinitionException ex) {
// not found -> check parent
if (this.parentBeanFactory != null) {
return this.parentBeanFactory.getBean(name);
}
throw ex;
}
// create bean instance
if (mergedBeanDefinition.isSingleton()) {
synchronized (this.singletonCache) {
// re-check singleton cache within synchronized block
sharedInstance = this.singletonCache.get(beanName);
if (sharedInstance == null) {
logger.info("Creating shared instance of singleton bean '" + beanName + "'");
sharedInstance = createBean(beanName, mergedBeanDefinition);
addSingleton(beanName, sharedInstance);
}
}
return getObjectForSharedInstance(name, sharedInstance);
}
else {
return createBean(name, mergedBeanDefinition);
}
}
}
protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition) throws BeansException {
if (mergedBeanDefinition.getDependsOn() != null) {
for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {
// guarantee initialization of beans that the current one depends on
getBean(mergedBeanDefinition.getDependsOn()[i]);
}
}
// bean 初始化并包装,也就是 new
BeanWrapper instanceWrapper = null;
if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mergedBeanDefinition.hasConstructorArgumentValues()) {
instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
}
else {
instanceWrapper = new BeanWrapperImpl(mergedBeanDefinition.getBeanClass());
initBeanWrapper(instanceWrapper);
}
Object bean = instanceWrapper.getWrappedInstance();
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
if (mergedBeanDefinition.isSingleton()) {
// 单例的bean 则添加到缓存中
addSingleton(beanName, bean);
}
// bean 属性注入
populateBean(beanName, mergedBeanDefinition, instanceWrapper);
try {
if (bean instanceof BeanNameAware) {
// bean 若实现接口 BeanNameAware 则调用 setBeanName 方法
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanFactoryAware) {
// bean 若实现接口 BeanFactoryAware 则调用 setBeanFactory 方法
((BeanFactoryAware) bean).setBeanFactory(this);
}
// 调用 BeanPostProcessor 执行 postProcessBeforeInitialization 方法
bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 若 bean 实现 InitializingBean 接口则执行 afterPropertiesSet 方法
// 若 bean 定义中定义了 init-method 属性则执行对应的init 方法
invokeInitMethods(bean, beanName, mergedBeanDefinition);
// 调用 BeanPostProcessor 执行 postProcessAfterInitialization 方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
"Initialization of bean failed", ex.getTargetException());
}
catch (Exception ex) {
throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
"Initialization of bean failed", ex);
}
return bean;
}
从 bean 的实例化过程中,Spring 容器在启动时只针对单例且非延迟加载的 bean 进行初始化;其他的 bean 只有在显示调用 getBean() 方法时才去实例化;下面将会对实例化过程中的详细过程进行说明。
Spring Bean 作用域
singleton 单例模式
Spring IoC 容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象。
<bean id="test" singleton="true" />
<bean scope="singleton" />
Spring 1.0 中通过 bean 定义属性 singleton='true'
表示单例; 在 Spring 2.x 之后版本改为定义属性 scope='singleton'
, 同时兼容 1.0 的配置
prototype 原型模式
每次通过Spring容器获取prototype定义的bean时,容器都将创建一个新的Bean实例,每个Bean实例都有自己的属性和状态
<bean id="test" singleton="false" />
<bean scope="prototype" />
Spring 1.0 中通过 bean 定义属性 singleton='false'
表示原型模式; 在 Spring 2.x 之后版本改为定义属性 scope='prototype'
, 同时兼容 1.0 的配置
Spring Bean 生命周期
image示例
public class LifecycleBean implements BeanNameAware, InitializingBean, BeanFactoryAware, ResourceLoaderAware, ApplicationContextAware, DisposableBean {
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("set bean factory");
}
public void setBeanName(String name) {
System.out.println("set bean name");
}
public void afterPropertiesSet() throws Exception {
System.out.println("Initializing Bean afterPropertiesSet");
}
public void setApplicationContext(ApplicationContext context) throws BeansException {
System.out.println("set application context");
}
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("set resource loader");
}
public void init () {
System.out.println("do init method");
}
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
System.out.println("post Process Before Initialization");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
System.out.println("post Process After Initialization");
return bean;
}
public void destroy() throws Exception {
System.out.println("do destroy ");
}
public void destroyMethod() throws Exception {
System.out.println("do destroy method");
}
}
public class PostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
if (bean instanceof LifecycleBean) {
((LifecycleBean) bean).postProcessBeforeInitialization(bean, name);
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
if (bean instanceof LifecycleBean) {
((LifecycleBean) bean).postProcessAfterInitialization(bean, name);
}
return bean;
}
}
spring 配置文件如下
<beans>
<bean id="lifecycleBean" class="org.springframework.beans.factory.LifecycleBean" init-method="init" />
<bean id="postProcessor" class="org.springframework.beans.factory.PostProcessor" />
</beans>
运行结果如下:
set bean name
set bean factory
set resource loader
set application context
post Process Before Initialization
Initializing Bean afterPropertiesSet
do init method
post Process After Initialization
do destroy
do destroy method
Spring Bean 注入方式
构造注入
<bean>
<constructor-arg index="1">
<value></value>
</constructor-arg>
</bean>
<bean autowire="constructor" />
当 bean 定义配置如以上方式的时候,会触发 autowireConstructor
(详细实现参考源码吧)
BeanWrapper instanceWrapper = null;
if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mergedBeanDefinition.hasConstructorArgumentValues()) {
instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
}
byType 注入
<bean autowire="byType" />
当 bean 定义配置如以上方式的时候,会触发 autowireByType
如下:
protected void autowireByType(String beanName, RootBeanDefinition mergedBeanDefinition,
BeanWrapper bw, MutablePropertyValues pvs) {
// 查找 bean 存在可写方法的非基本数据类型的成员变量
String[] propertyNames = unsatisfiedObjectProperties(mergedBeanDefinition, bw);
for (int i = 0; i < propertyNames.length; i++) {
String propertyName = propertyNames[i];
// look for a matching type
// 获取成员变量的类型
Class requiredType = bw.getPropertyDescriptor(propertyName).getPropertyType();
// 查找成员变量对应的 bean 实例
Map matchingBeans = findMatchingBeans(requiredType);
if (matchingBeans != null && matchingBeans.size() == 1) {
// 成员变量查找到匹配的bean实例,有且只有一个的时候
// 将属性名和属性值 添加到 PropertyValues 中
pvs.addPropertyValue(propertyName, matchingBeans.values().iterator().next());
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" +
matchingBeans.keySet().iterator().next() + "'");
}
}
else if (matchingBeans != null && matchingBeans.size() > 1) {
// 当存在多个同类型的实例时 抛出异常
throw new UnsatisfiedDependencyException(beanName, propertyName,
"There are " + matchingBeans.size() + " beans of type [" + requiredType + "] for autowire by type. " +
"There should have been 1 to be able to autowire property '" + propertyName + "' of bean '" + beanName + "'.");
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by type: no matching bean found");
}
}
}
}
byName 注入
<bean autowire="byName" />
当 bean 定义配置如以上方式的时候,会触发 autowireByName
如下:
protected void autowireByName(String beanName, RootBeanDefinition mergedBeanDefinition,
BeanWrapper bw, MutablePropertyValues pvs) {
// 查找 bean 存在可写方法的非基本数据类型的成员变量
String[] propertyNames = unsatisfiedObjectProperties(mergedBeanDefinition, bw);
for (int i = 0; i < propertyNames.length; i++) {
String propertyName = propertyNames[i];
// 在 Spring 容器中查找是否存在以 propertyName 命名的 bean definition
if (containsBean(propertyName)) {
// 实例化依赖的 bean, 并添加到 MutablePropertyValues 中
Object bean = getBean(propertyName);
pvs.addPropertyValue(propertyName, bean);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
set 注入
<bean>
<property name="age">
<value>11</value>
</property>
</bean>
当 bean 定义配置如上,或者采用 byName, byType 的注入方式时,都会调用 applyPropertyValues
方法完成属性的注入。(详细实现参考源码吧)
Spring Bean 注解式注入
自 Spring 2.5 版本之后,支持通过注解方式实现 Bean 的自动注入,譬如
@Autowired
,@Resource
等注解
为了引入注解式自动注入, Spring 在 2.x 版本中新增了 InstantiationAwareBeanPostProcessor
接口,该接口继承 BeanPostProcessor
并新增了方法 postProcessPropertyValues
; 该方法主要实现
Post-process the given property values before the factory applies them to the given bean
Autowired 注解
采用 Autowired 注解实现自动注入,需在配置文件中配置
AutowiredAnnotationBeanPostProcessor
Bean
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
从 AutowiredAnnotationBeanPostProcessor
构造可以看出其支持 @Autowired
,@Value
,@Inject
注解的自动注入。 下面大概看下其如何实现自动注入
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
// 查找 bean 中需要自动注入的元数据,包括 field, method
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
try {
// 实现注入
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
Resource 注解
采用 Resource 注解实现自动注入,需在配置文件中配置
CommonAnnotationBeanPostProcessor
Bean
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
从 CommonAnnotationBeanPostProcessor
构造可以看出,该类同时支持对注解 @PostConstruct
, @PreDestroy
生效。
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
// 查找 bean 中标注有 @Resource 注解的 Field, method
InjectionMetadata metadata = findResourceMetadata(bean.getClass());
try {
// 实现注入
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 查找 bean 定义中标注了 PostConstruct 注解的方法
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 调用指定 post construct method
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Couldn't invoke init method", ex);
}
return bean;
}
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
// 查找 bean 定义中标注了 PreDestroy 注解的方法
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 调用指定 destroy method
metadata.invokeDestroyMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
String msg = "Invocation of destroy method failed on bean with name '" + beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
}
else {
logger.warn(msg + ": " + ex.getTargetException());
}
}
catch (Throwable ex) {
logger.error("Couldn't invoke destroy method on bean with name '" + beanName + "'", ex);
}
}
private LifecycleMetadata buildLifecycleMetadata(Class clazz) {
final boolean debug = logger.isDebugEnabled();
LinkedList<LifecycleElement> initMethods = new LinkedList<LifecycleElement>();
LinkedList<LifecycleElement> destroyMethods = new LinkedList<LifecycleElement>();
Class<?> targetClass = clazz;
do {
LinkedList<LifecycleElement> currInitMethods = new LinkedList<LifecycleElement>();
LinkedList<LifecycleElement> currDestroyMethods = new LinkedList<LifecycleElement>();
// 遍历 bean 的所有方法
for (Method method : targetClass.getDeclaredMethods()) {
if (this.initAnnotationType != null) {
// 判断 method 是否标注了 @PostConstruct 注解
if (method.getAnnotation(this.initAnnotationType) != null) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (debug) {
logger.debug("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
}
if (this.destroyAnnotationType != null) {
// 判断 method 是否标注了 @PreDestroy 注解
if (method.getAnnotation(this.destroyAnnotationType) != null) {
currDestroyMethods.add(new LifecycleElement(method));
if (debug) {
logger.debug("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
}
}
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}
<context: annotation-config>
为了简化 Spring 配置文件中的 bean 配置,Spring 提供了 <context: annotation-config> 标签自动加载
AutowiredAnnotationBeanPostProcessor
,CommonAnnotationBeanPostProcessor
等 bean。
在 spring-context 包 resources/META-INF 下的 spring.handlers 文件中配置如下:
http\://www.springframework.org/schema/context=org.springframework.context.config.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());
}
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
// 加载注册 AutowiredAnnotationBeanPostProcessor
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
// 加载注册 RequiredAnnotationBeanPostProcessor
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
// 加载注册 CommonAnnotationBeanPostProcessor
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
ClassLoader cl = AnnotationConfigUtils.class.getClassLoader();
def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
return beanDefs;
}
可以看出在 Spring 启动时,通过解析 <context: annotation-config> 标签,完成对 CommonAnnotationBeanPostProcessor
, AutowiredAnnotationBeanPostProcessor
的加载注册,进而实现通过注解方式的自动注入。
小结
BeanFactory & ApplicationContext
imageBeanFactoryPostProcessor & BeanPostProcessor
-
BeanFactoryPostProcessor
是ApplicationContext
在 BeanFactory 完成创建后对其进行后置处理的接口 -
BeanPostProcessor
是BeanFactory
在 Bean 完成实例化对其进行的后置处理接口
BeanFactory & FactoryBean
- BeanFactory 是 Spring 框架底层的核心接口,其提供了创建 bean,获取 bean 等核心功能。
- FactoryBean 是生产 bean 的一个模式,也就是以工厂模式的方式生产 bean。
网友评论