Spring: InitializingBean的作用
http://blog.csdn.net/mqboss/article/details/7452331
專案中管理事務比較簡單,用TransactionTemplate,就直接以TransactionTemplate為入口開始學習。
TransactionTemplate的原始碼如下:- public class TransactionTemplate extends DefaultTransactionDefinition
- implements TransactionOperations, InitializingBean{
- .
- .
- .
- }
TransactionTemplate繼承了DefaultTransactionDefinition,實現了TransactionOperations,InitializingBean介面。InitializingBean介面
InitializingBean介面為bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是繼承該介面的類,在初始化bean的時候會執行該方法。
- import org.springframework.beans.factory.InitializingBean;
- public class TestInitializingBean implements InitializingBean{
- @Override
- public void afterPropertiesSet() throws Exception {
- System.out.println("ceshi InitializingBean");
- }
- public void testInit(){
- System.out.println("ceshi init-method");
- }
- }
配置檔案如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
- <bean id="testInitializingBean" class="com.TestInitializingBean" ></bean>
- </beans>
Main主程式如下:
- public class Main {
- public static void main(String[] args){
- ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/java/com/beans.xml");
- }
- }
執行Main程式,列印如下結果:
ceshi InitializingBean
這說明在spring初始化bean的時候,如果bean實現了InitializingBean介面,會自動呼叫afterPropertiesSet方法。
問題:實現InitializingBean介面與在配置檔案中指定init-method有什麼不同?
修改配置檔案,加上init-method配置,修改如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
- <bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>
- </beans>
在配置檔案中加入init-method="testInit"。
執行Main程式,列印如下結果:
ceshi InitializingBean
ceshi init-method
由結果可看出,在spring初始化bean的時候,如果該bean是實現了InitializingBean介面,並且同時在配置檔案中指定了init-method,系統則是先呼叫afterPropertiesSet方法,然後在呼叫init-method中指定的方法。
這方式在spring中是怎麼實現的?
通過檢視spring的載入bean的原始碼類(AbstractAutowireCapableBeanFactory)可看出其中奧妙
AbstractAutowireCapableBeanFactory類中的invokeInitMethods講解的非常清楚,原始碼如下:
- protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
- throws Throwable {
- //判斷該bean是否實現了實現了InitializingBean介面,如果實現了InitializingBean介面,則只掉呼叫bean的afterPropertiesSet方法
- boolean isInitializingBean = (bean instanceof InitializingBean);
- if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
- if (logger.isDebugEnabled()) {
- logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
- }
- if (System.getSecurityManager() != null) {
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
- public Object run() throws Exception {
- //直接呼叫afterPropertiesSet
- ((InitializingBean) bean).afterPropertiesSet();
- return null;
- }
- },getAccessControlContext());
- } catch (PrivilegedActionException pae) {
- throw pae.getException();
- }
- }
- else {
- //直接呼叫afterPropertiesSet
- ((InitializingBean) bean).afterPropertiesSet();
- }
- }
- if (mbd != null) {
- String initMethodName = mbd.getInitMethodName();
- //判斷是否指定了init-method方法,如果指定了init-method方法,則再呼叫制定的init-method
- if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
- !mbd.isExternallyManagedInitMethod(initMethodName)) {
- //進一步檢視該方法的原始碼,可以發現init-method方法中指定的方法是通過反射實現
- invokeCustomInitMethod(beanName, bean, mbd);
- }
- }
- }
總結:
1:spring為bean提供了兩種初始化bean的方式,實現InitializingBean介面,實現afterPropertiesSet方法,或者在配置檔案中同過init-method指定,兩種方式可以同時使用
2:實現InitializingBean介面是直接呼叫afterPropertiesSet方法,比通過反射呼叫init-method指定的方法效率相對來說要高點。但是init-method方式消除了對spring的依賴
3:如果呼叫afterPropertiesSet方法時出錯,則不呼叫init-method指定的方法。
4:TransactionTemplate實現InitializingBean介面,主要是判斷transactionManager是否已經初始化,如果沒有則丟擲異常。原始碼如下:
- public void afterPropertiesSet() {
- if (this.transactionManager == null) {
- throw new IllegalArgumentException("Property 'transactionManager' is required");
- }
- }
相關文章
- spring InitializingBean介面SpringBean
- Spring核心介面之InitializingBeanSpringBean
- spring的作用Spring
- Spring的作用域以及RequestContextListener作用SpringContext
- Spring框架的基本作用Spring框架
- spring @component的作用Spring
- Spring中Bean的作用域SpringBean
- spring ContextLoaderListener的作用SpringContext
- Spring在ssh中的作用Spring
- Spring Bean作用域SpringBean
- spring中各個類的作用Spring
- Spring 當中的Bean 作用域SpringBean
- [spring-core]作用域Spring
- Spring中Bean的作用域有哪些?SpringBean
- spring @component 的作用詳細介紹Spring
- spring bean的作用域和生命週期SpringBean
- Spring裝配Bean(六)Bean的作用域SpringBean
- spring的懶載入,有什麼作用?Spring
- 【Spring註解驅動開發】使用InitializingBean和DisposableBean來管理bean的生命週期,你真的瞭解嗎?SpringBean
- Spring bean 通過實現 InitializingBean ,DisposableBean 介面實現初始化方法和銷燬前操作SpringBean
- Spring在開發專案中起的作用Spring
- Spring學習(二)Bean 作用域SpringBean
- Spring AOP 對Spring MVC的Controller切面攔截不起作用SpringMVCController
- spring_bean的作用域,spring使用外部屬性檔案和spring_SpEL(三)SpringBean
- Spring-bean作用域scope詳解SpringBean
- Spring Security配置好了不起作用Spring
- 詳解Spring中Bean的作用域與生命週期SpringBean
- Spring MVC + Mybatis + Spring Aop宣告式事務管理沒有作用SpringMVCMyBatis
- web.xml中的contextConfigLocation在spring中的作用WebXMLContextSpring
- 【面試普通人VS高手】Spring 中Bean的作用域有哪些?面試SpringBean
- spring心得2--bean的生命週期@Spring監聽器的作用@Spring初始化容器案例分析@web專案使用SpringBeanWeb
- Spring學習歷程---request,session與globalSession作用域SpringSession
- js的作用域、作用域鏈JS
- js的作用域和作用域鏈JS
- js的作用域與作用域鏈JS
- Spring中建立帶原型作用域bean5種方法Spring原型Bean
- Java中的volatile的作用和synchronized作用Javasynchronized
- Spring 框架基礎(02):Bean的生命週期,作用域,裝配總結Spring框架Bean