zoukankan      html  css  js  c++  java
  • Spring的InitializingBean和initmethod(转载)

    转自http://www.2cto.com/kf/201201/116580.html

    Spring在设置完一个bean所有的属性后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的 afterPropertiesSet方法。另外,如果bean是单例的,则afterPropertiesSet方法只会被调用一次;否则每次创建 bean时afterPropertiesSet方法都会被重新调用.
    Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起 了。通常情况下不建议直接实现InitializingBean,而是用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法,这可以在一个bean的配置文件中通过init-method声明:
    <bean id="testBean" class="TestClass" init-method="initialize"/>
    spring要求这个init-method方法是一个无参数的方法。
    Spring要求init-method是一个无参数的方法,如果init-method指定的方法中有参数,那么Spring将会抛出java.lang.NoSuchMethodException
    init-method指定的方法可以是public、protected以及private的,并且方法也可以是final的。
    init-method指定的方法可以是声明为抛出异常的,就像这样:
           final protected void init() throws Exception{
               System.out.println("init method...");
               if(true) throw new Exception("init exception");
        }
    如果在init-method方法中抛出了异常,那么Spring将中止这个Bean的后续处理,并且抛出一个org.springframework.beans.factory.BeanCreationException异常。
    如果一个bean同时实现了这两种方式的初始化配置,则spring会先调用afterPropertiesSet方法,然后通过反射调用init- method,任何一个方法出错都会导致spring创建bean失败.如果afterPropertiesSet方法调用失败,也不会再继续执行 init-mehtod方法。
    org.springframework.beans.factory.support. AbstractAutowireCapableBeanFactory完成一个Bean初始化方法的调用工作。 AbstractAutowireCapableBeanFactory是XmlBeanFactory的超类,再 AbstractAutowireCapableBeanFactory的invokeInitMethods方法中实现调用一个Bean初始化方法:
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.java:
    view plainprint?
    //…… 
    //在一个bean的合作者设备完成后,执行一个bean的初始化方法。 
    protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mergedBeanDefinition) 
     throws Throwable { 
    //判断bean是否实现了InitializingBean接口 
    if (bean instanceof InitializingBean) { 
    if (logger.isDebugEnabled()) { 
    logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); 

    //调用afterPropertiesSet方法 
    ((InitializingBean) bean).afterPropertiesSet(); 

    //判断bean是否定义了init-method 
    if(mergedBeanDefinition!=null&&mergedBeanDefinition.getInitMethodName() != null) { 
    //调用invokeCustomInitMethod方法来执行init-method定义的方法 
    invokeCustomInitMethod(beanName, bean, mergedBeanDefinition.getInitMethodName()); 


    //执行一个bean定义的init-method方法 
    protected void invokeCustomInitMethod(String beanName, Object bean, String initMethodName) 
    throws Throwable { 
    if (logger.isDebugEnabled()) { 
    logger.debug("Invoking custom init method '" + initMethodName + 
    "' on bean with name '" + beanName + "'"); 

    //使用方法名,反射Method对象 
    Method initMethod = BeanUtils.findMethod(bean.getClass(), initMethodName, null); 
    if (initMethod == null) { 
    throw new NoSuchMethodException( 
    "Couldn't find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'"); 

    //判断方法是否是public 
    if (!Modifier.isPublic(initMethod.getModifiers())) { 
    //设置accessible为true,可以访问private方法。 
                         initMethod.setAccessible(true); 

    try { 
    //反射执行这个方法 
    initMethod.invoke(bean, (Object[]) null); 

    catch (InvocationTargetException ex) { 
    throw ex.getTargetException(); 


    //……….. 
    通过分析上面的源代码我们可以看到,init-method是通过反射执行的,而afterPropertiesSet是直接执行的。所以 afterPropertiesSet的执行效率比init-method要高,不过init-method消除了bean对Spring依赖。在实际使 用时我推荐使用init-method。  

  • 相关阅读:
    noi 2011 noi嘉年华 动态规划
    最小乘积生成树
    noi 2009 二叉查找树 动态规划
    noi 2010 超级钢琴 划分树
    noi 2011 阿狸的打字机 AC自动机
    noi 2009 变换序列 贪心
    poj 3659 Cell Phone Network 动态规划
    noi 2010 航空管制 贪心
    IDEA14下配置SVN
    在SpringMVC框架下建立Web项目时web.xml到底该写些什么呢?
  • 原文地址:https://www.cnblogs.com/lingear/p/2833102.html
Copyright © 2011-2022 走看看