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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • [LeetCode] Search in Rotated Sorted Array [35]

    [LeetCode] Search in Rotated Sorted Array [35]

    2022年1月29日
    61
  • Oracle的DDL和DML

    Oracle知识点整理(二)前言SQLSQL的分类Oracle的数据类型NUMBERCHARVARCHAR/VARCHAR2DATESQL操作创建表查看表结构删除表修改表修改表名修改表的结构新增字段修改字段删除字段新增数据修改数据删除数据前言这一章主要介绍一下SQL中的DDL和DML,以Oracle为例。SQLSQL:StructuredQueryLanguage结构化查询语言SQL是在关系型数据库上执行数据操作、检索、维护所使用的标准语言。所有的数据库都使用相同或相似的语言。SQL

    2022年4月8日
    74
  • Python 文件操作

    Python 文件操作

    2021年8月21日
    345
  • goland激活码最新-激活码分享

    (goland激活码最新)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlTR0LFTT656-eyJsa…

    2022年3月22日
    57
  • GHO文件转iso文件能启动安装

    GHO文件转iso文件能启动安装言:目前网上流传的gho转iso教程都是用ultraiso替换gho文件的方法,但是这种方法经过实际使用存在两个缺陷,1.只适用XP,超过800M的时候替换会提示升级DVD格式,但是升级之后会导致不能启动,不升级无法替换,2.不能有效的控制启动盘的来源,只能找别人做好的进行替换鉴于以上两点,有必要重新找个方法准备工具1.IT天空的PE制作工具下载地址2.win7的gho文件下载地址:3.winISO下载地址:http://lt2.mqego.com/soft1/winiso

    2022年7月13日
    22
  • java串口通信

    java串口通信java串口通信,由于没有相应的串口硬件,选了一款windows串口虚拟机机器1.准备串口模拟器LaunchVirtualSerialPortDriver下载地址模拟两对四个串口,

    2022年7月1日
    21

发表回复

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

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