使用了 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 完成實例化對其進行的後置處理接口