使用了 Spring 多年,可是对其底层的一些实现仍是只知其一;不知其二,一些概念比较模糊;故决定从新拾起,加深对 Spring 的认识。java
Spring 在通过多年的演进过程当中,其功能愈来愈丰富,组件愈来愈多;为了不在阅读源码的过程当中深陷泥潭中,决定采用最原始的版本 1.0; 但又不局限于 1.0 版本。node
在本文中,经过经常使用的构造
ClassPathXmlApplicationContext
实例来做为对 Spring 实现分析的入口
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
经过调用链追踪,Spring 容器启动核心操做由 AbstractApplicationContext
类中 refresh
方法实现spring
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 容器在启动过程当中,主要完成如下流程 :json
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 在容器启动过程当中的各个环节的实现进行详细说明
经过对 refreshBeanFactory
方法的调用链追踪,能够看到在 DefaultXmlBeanDefinitonParser
类的 registerBeanDefinitions
方法中实现对 Spring Bean 定义的解析及注册。app
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 中。
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 IoC 容器中只会存在一个共享的Bean实例,不管有多少个Bean引用它,始终指向同一对象。
<bean id="test" singleton="true" /> <bean scope="singleton" />
Spring 1.0 中经过 bean 定义属性 singleton='true'
表示单例; 在 Spring 2.x 以后版本改成定义属性 scope='singleton'
, 同时兼容 1.0 的配置框架
每次经过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 的配置ide
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 配置文件以下post
<beans> <bean id="lifecycleBean" class="org.springframework.beans.factory.LifecycleBean" init-method="init" /> <bean id="postProcessor" class="org.springframework.beans.factory.PostProcessor" /> </beans>
运行结果以下:ui
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
<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); }
<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"); } } } }
<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"); } } } }
<bean> <property name="age"> <value>11</value> </property> </bean>
当 bean 定义配置如上,或者采用 byName, byType 的注入方式时,都会调用 applyPropertyValues
方法完成属性的注入。(详细实现参考源码吧)
自 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 注解实现自动注入,需在配置文件中配置
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 注解实现自动注入,需在配置文件中配置
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); }
为了简化 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
的加载注册,进而实现经过注解方式的自动注入。
BeanFactoryPostProcessor
是 ApplicationContext
在 BeanFactory 完成建立后对其进行后置处理的接口BeanPostProcessor
是 BeanFactory
在 Bean 完成实例化对其进行的后置处理接口