spring InitializingBean

spring InitializingBean

大家好,又见面了,我是全栈君。

先说总结:


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”);


        }


    }



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);


            }


        }


    }



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108602.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • IoT — (四) 物联网系统架构介绍[通俗易懂]

    IoT — (四) 物联网系统架构介绍[通俗易懂]  物联网(IoT)是目前最新最热的技术热点之一,也是这个信息化时代的重要发展节点。相对于互联网而言,物联网的本质在于“万物相连”。物联网的核心和基础仍然是互联网,是在互联网基础上延伸和扩展的网络;其用户端延伸和扩展到了任何物品与物品之间,进行信息交换和通信,也就是物物相息。  物联网操作系统概述:尽管物联网的发展形态受到普遍看好和关注,但是“连接、区别、识别、沟通、操作”这五大问题一直如影随形…

    2022年9月17日
    0
  • 京东活动+自动运行脚本+签到2021.05.26更新

    京东活动+自动运行脚本+签到2021.05.26更新先下载Node.js运行环境https://nodejs.org/en下载14.15.4版本。WIN7下载12.20的版本https://nodejs.org/dist/latest-v12.x/node-v12.20.1-x64.msi。只需要一路安装就可以。检测是否安装成功:点击开始-运行-cmd(win+R),打开dos,输入“node–version”检查Node.js版本:只要有显示就说明没问题了。每天大概300-400个京豆,有时候现金红包会有6元左右。下载脚本包:https://..

    2022年7月23日
    9
  • Latex大括号及多行公式[通俗易懂]

    Latex大括号及多行公式[通俗易懂]array中lrc表示各列内容的居左、居中、居右。.\begin{equation}\left\{\begin{array}{lr}x=\dfrac{3\pi}{2}(1+2t)\cos(\dfrac{3\pi}{2}(1+2t)),&\\y=s,&0\leqs\leqL,|t|\le

    2022年10月11日
    1
  • soft thresholding and hard thresholding

    soft thresholding and hard thresholding今天在看MichaelElad大牛的论文《OntheRoleofSparseandRedundantRepresentationsinImageProcessing》中,看到了softthresholding和hardthresholding这两个概念,很是不明白,所以上网查了一些资料,先把网上查的东西贴出来讨论下。网上资料大体是说这是指两类的函数,分别

    2022年6月8日
    57
  • 8种垂直居中的方法

    八种垂直居中的方法垂直居中的需求经常遇到,通过资料实践了八种垂直居中的方法。以下的方法都围绕着该HTML展开HTML代码<divstyle=”width:300px;height:300px;”class=”wrap”><divstyle=”width:100px;height:100px”class=”box”></div></div>CSS方法1(常用):display:flex.wra

    2022年4月4日
    33
  • poj2488 A Knight’s Journey

    poj2488 A Knight’s Journey

    2021年5月27日
    89

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号