转:spring中InitailizingBean接口的简单理解
转自:https://www.cnblogs.com/wxgblogs/p/6849782.html
spring中InitializingBean接口使用理解
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。
测试程序如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import org.springframework.beans.factory.InitializingBean;import org.springframework.stereotype.Service;public class InitBean implements InitializingBean{ public void afterPropertiesSet() throws Exception { System.out.println("启动时自动执行 afterPropertiesSet..."); } public void init(){ System.out.println("init method..."); }} |
配置文件如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" 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.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd" default-lazy-init="true"> <bean id="initBean" class="com.netease.nsip.spring.InitBean" init-method="init"> </bean></beans> |
Main主程序如下:
|
1
2
3
4
5
6
7
8
9
10
|
import org.springframework.context.ApplicationContext;import org.springframework.context.support.FileSystemXmlApplicationContext;public class Main { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext("classpath:/applicationContext-core.xml"); context.getBean("initBean"); }} |
运行Main程序,打印如下结果:
|
1
2
|
启动时自动执行 afterPropertiesSet...init method... |
这说明在spring初始化bean的时候,如果bean实现了InitializingBean接口,会自动调用afterPropertiesSet方法。
问题:实现InitializingBean接口与在配置文件中指定init-method有什么不同?由结果可看出,在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。这方式在spring中是怎么实现的?通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可看出其中奥妙AbstractAutowireCapableBeanFactory类中的invokeInitMethods讲解的非常清楚,源码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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); } } } |
总结:
- spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用
- 实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖
- 如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
spring中InitializingBean接口使用理解
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。
测试程序如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import org.springframework.beans.factory.InitializingBean;import org.springframework.stereotype.Service;public class InitBean implements InitializingBean{ public void afterPropertiesSet() throws Exception { System.out.println("启动时自动执行 afterPropertiesSet..."); } public void init(){ System.out.println("init method..."); }} |
配置文件如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" 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.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd" default-lazy-init="true"> <bean id="initBean" class="com.netease.nsip.spring.InitBean" init-method="init"> </bean></beans> |
Main主程序如下:
|
1
2
3
4
5
6
7
8
9
10
|
import org.springframework.context.ApplicationContext;import org.springframework.context.support.FileSystemXmlApplicationContext;public class Main { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext("classpath:/applicationContext-core.xml"); context.getBean("initBean"); }} |
运行Main程序,打印如下结果:
|
1
2
|
启动时自动执行 afterPropertiesSet...init method... |
这说明在spring初始化bean的时候,如果bean实现了InitializingBean接口,会自动调用afterPropertiesSet方法。
问题:实现InitializingBean接口与在配置文件中指定init-method有什么不同?由结果可看出,在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。这方式在spring中是怎么实现的?通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可看出其中奥妙AbstractAutowireCapableBeanFactory类中的invokeInitMethods讲解的非常清楚,源码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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); } } } |
总结:
- spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用
- 实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖
- 如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
转:spring中InitailizingBean接口的简单理解的更多相关文章
- Spring中Ordered接口简介
目录 前言 Ordered接口介绍 Ordered接口在Spring中的使用 总结 前言 Spring中提供了一个Ordered接口.Ordered接口,顾名思义,就是用来排序的. Spring是一个 ...
- Spring中Bean及@Bean的理解
Spring中Bean及@Bean的理解 Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法: 一.Bean是啥 1.Java面向对象,对象有方法和属性, ...
- C#中事件流程的简单理解
C#中事件流程的简单理解 C#中事件基于委托,要理解事件要先理解委托,但是现在我还没想好怎么写委托,如果不懂委托可以先找找委托的文章 事件基于委托,为委托提供了一种发布/订阅机制 一上来就是这句话,很 ...
- spring中InitializingBean接口使用理解
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法. 测试程序如下: imp ...
- spring中InitializingBean接口使用理解(转)
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法. 测试程序如下: imp ...
- Java集合框架中List接口的简单使用
Java集合框架可以简单的理解为一种放置对象的容器,和数学中的集合概念类似,Java中的集合可以存放一系列对象的引用,也可以看做是数组的提升,Java集合类是一种工具类,只有相同类型的对象引用才可以放 ...
- Spring学习(二)——Spring中的AOP的初步理解[转]
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...
- 对Spring中IOC和DI的理解
前几篇讲了Spring中IOC和DI的用法,本篇应该放到三篇之前,但一直没有想到好的讲解方式,后参考https://blog.csdn.net/luoyepiaoxue2014/article/det ...
- spring中ApplicationContextAware接口描述
项目中使用了大量的工厂类,采用了简单工厂模式: 通过该工厂类可以获取指定的处理器bean,这些处理器bean我们是从spring容器中获取的,如何获取,是通过实现ApplicationContextA ...
随机推荐
- react 路由
react 提供了实现路由的方式,不过需要我们下载插件 react-router-dom 当我们下载好了插件,然后我们可以通过 import {} from 'react-router-dom' 来引 ...
- rocketmq的生产者生产消息
package com.bfxy.rocketmq.model; import org.apache.rocketmq.client.exception.MQClientException;impor ...
- How to run a VBA macro when new mail is received in Outlook
It can be very useful to run a VBA macro when new mail is received in Outlook. A customer asked me t ...
- net.sf.json.JSONObject处理 "null" 字符串的一些坑
转: net.sf.json.JSONObject处理 "null" 字符串的一些坑 2018年05月02日 16:41:25 大白能 阅读数:7026 版权声明:本文为博主原 ...
- 看日志有没有 出现错误的字段 (如 crash ) 查找app闪退
查看monkey的错误 在log里面查找 error / crashed / Exception 1. ANR问题:在日志中搜索“ANR” 2.崩溃问题:在日志中搜索“Exception” F ...
- CTF—攻防练习之HTTP—SQL注入(SSI注入)
主机:192.168.32.152 靶机:192.168.32.161 ssI是赋予html静态页面的动态效果,通过ssi执行命令,返回对应的结果,若在网站目录中发现了.stm .shtm .shtm ...
- selenium知识思维导图|从元素定位到操作断言,助你快速入门自动化测试
为什么要进行自动化测试? 缩短测试周期,节省成本. 避免人为出错,提高准确性和可靠性. 获取需求覆盖率,代码覆盖率,提供衡量软件质量的指标. 自动化测试的条件? 手工测试完成后. 项目周期长,需求稳定 ...
- 用户及用户组管理(week1_day4)
本节内容 useradd userdel usermod groupadd groupdel 用户管理 为什么需要有用户? 1. linux是一个多用户系统 2. 权限管理(权限最 ...
- vim编辑器详解(week1_day3)
vi编辑器 作用:编辑文本文件中的内容的工具 命令历史 末行模式中,以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中 ...
- 'Python.exe' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
说明python不能被调用,需要为他制定正确的路径.0=0(win10想要打开任何东西,左下角搜索框) 1.打开 python,输入import os 输入os.getcwd,得到路径. 2.打开 编 ...