转: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 ...
随机推荐
- java使用解压zip文件,文件名乱码解决方案
File outFileDir = new File(outDir);if (!outFileDir.exists()) { boolean isMakDir = outFileDir.mkdirs( ...
- 卸载阿里云盾(安骑士)监控&屏蔽云盾IP
卸载阿里云盾监控 wget http://update.aegis.aliyun.com/download/uninstall.sh chmod +x uninstall.sh ./uninstall ...
- [转]springboot启动原理
参考文章:https://www.jianshu.com/p/ef6f0c0de38f
- yum源安装mysql数据库 添加密码
学习mysql数据库时,安装的问题一直很烦恼,linux的不同版本的安装方式都可能不同,这里是我学习时的一些总结.也是刚刚开始学习,大佬勿喷,谢谢啦!!! 1.查看是否已经安装 2.如果没安装 yum ...
- vue echarts圆角阴影效果
series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20], itemStyle: { normal: { barBorder ...
- Python 中的type和object详解
1.python中的类 Python2.x 中的类分为两种,一种是所有继承自object的新式类,另外一种是经典类classobj, 新式类的写法: class A(object): pass 经典类 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型
笔记 2.技术选型和学后水平 简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度, 1.IDEA JDK8 Maven SpringBoot基础 Linux 2.理 ...
- 如何实现Eclipse默认编码为UTF-8
1 Window->Preferences->General->Workspace,右边Text file encoding选择Other->UTF-8 2 Window-&g ...
- YAML基础知识及搭建一台简洁版guestbook
一,前言 前面我们已经搭建过简易版k8s集群了,在此基础上可以搭建一个简洁版guestbook ,以便来学习k8s创建pod的整个过程. 二,在此之前,我们还需要学习一下YAML基础知识 YAML 基 ...
- C++中类中常规变量、const、static、static const(const static)成员变量的声明和初始化
C++类有几种类型的数据成员:普通类型.常量(const).静态(static).静态常量(static const).这里分别探讨以下他们在C++11之前和之后的初始化方式. c++11之前版本的初 ...