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


            }


        }


    }



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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 福利福利~262集前端免费视频!「建议收藏」

    福利福利~262集前端免费视频!「建议收藏」作者:技术胖原文地址:https://juejin.im/post/5c11bf145188252704368b98来源:掘金2018还有十几天就要过完了,我觉的这一年我的成长并不是很快,有很多

  • 什么是渗透_mitotracker deep red

    什么是渗透_mitotracker deep red0x00简介Mimikatz是一款功能强大的轻量级调试神器,通过它你可以提升进程权限注入进程读取进程内存,当然他最大的亮点就是他可以直接从lsass.exe 进程中获取当前登录系统用

  • SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter(“name”)无法获取参数值问题分析

    SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter(“name”)无法获取参数值问题分析一:问题demo展示在开发新需求,调试代码的时候发现一个问题,就是HttpServletRequest 获取不到ajax post请求的json参数!下面是伪代码是整个请求的逻辑!1.前台JS请求代码(伪代码)

  • mit6.033_mit6.830

    mit6.033_mit6.8301. CPU设计权衡2. 处理器性能3. 提示:Beta指令集4. 方法:提升特性5. 多端口寄存器文件6. 寄存器文件时序7. ALU指令8. 指令获取/解码9. ALUOP数据路径110. ALUOP数据路径211. ALU操作(带有常量)112. ALU操作(带有常量)213. load指令114. load指令215. store指令116. store指令217. JMP指令118. JMP指令219. BEQ/BNE

  • WINDOWS Platform SDK 下载[通俗易懂]

    WINDOWS Platform SDK 下载[通俗易懂]最近由于需要使用IPV6方面的开发资料,下载了WINDWOS网络编程相关的代码,发现在VC6.0上无法编译,猜想可能是SDK的版本较低,于是网上找来个:http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm 下载后,安装既可以实现IPV6在VC6.0平台编译调试。

  • 最全的ios系统导出微信聊天记录&生成词云教程

    首先放一张我的iPhone手机导出微信聊天记录生成的词云效果图(个别敏感词汇请大家自行忽略hhh):对于如何导出手机上的微信聊天记录,网上绝大部分教程提到的“楼月微信聊天记录导出恢复助手”和“手机博士微信聊天记录查看”等软件都是收费的,免费版本只能查看很少的几条聊天记录并且不能导出。在这里提供一种绝对免费的方法可以方便地导出微信聊天记录,后面附上根据聊天记录生成词云的教程。由于我个人的手机是i…

发表回复

您的电子邮箱地址不会被公开。

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