spring启动加载程序的几种方法介绍
作者:OnMyWay--YAO 发布时间:2022-03-11 14:15:32
关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种:
第一种:通过注解@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class DataInitializer{
@PostConstruct
public void initMethod() throws Exception {
System.out.println("initMethod 被执行");
}
@PreDestroy
public void destroyMethod() throws Exception {
System.out.println("destroyMethod 被执行");
}
}
第二种是:通过 在xml中定义init-method 和 destory-method方法
public class DataInitializer{
public void initMethod() throws Exception {
System.out.println("initMethod 被执行");
}
public void destroyMethod() throws Exception {
System.out.println("destroyMethod 被执行");
}
}
<bean id="dataInitializer" class="com.somnus.demo.DataInitializer" init-method="initMethod" destory-method="destroyMethod"/>
第三种是: 通过bean实现InitializingBean和 DisposableBean接口
import org.springframework.beans.factory.DisposableBean;
public class DataInitializer implements InitializingBean,DisposableBean{
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet 被执行");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy 被执行");
}
}
其中第一种和第二种是同一种形式,只不过一种xml配置,另外一种采用注解形式罢了,有很大区别的是第三种,如果同一个bean同时采用两种方式初始化的时候执行某个方法,首先在执行顺序上就会体现出来。
先执行afterPropertiesSet(),后执行initMethod()
这里我们看下源码
这方式在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);
}
}
总结:
1:spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用
2:实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖
3:如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
来源:http://blog.csdn.net/aa2484219/article/details/51261227
猜你喜欢
- 一、引入pom<?xml version="1.0" encoding="UTF-8"?>
- 学习Java 本身是一个挺枯燥的过程,说白了就是每天敲代码而已。但如果换一种思路,可以编写各种各样的程序,不仅加深对代码的理解,同时提高兴趣
- 本文实例讲述了C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题。分享给大家供大家参考,具体如下:一、理论
- ArrayList和LinkedList都实现了List接口,有以下的不同点:1、ArrayList是基于索引的数据接口,它的底层是数组。它
- mybatis的环境搭建:1、创建maven工程并且导入坐标:即我们需要在pop.xml文件中添加我们需要的依赖具体方法:搜索maven中央
- 在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来
- 本文实例为大家分享了Java实现人机猜拳游戏的具体代码,供大家参考,具体内容如下实现:User类public class User { pr
- 本文实例为大家分享了C#绘制饼状图和柱状图的具体代码,供大家参考,具体内容如下#代码如下:using System;using System
- 本文实例讲述了Java基于JDBC实现事务,银行转账及货物进出库功能。分享给大家供大家参考,具体如下:1. 转账业务转账必须执行2个sql语
- 这个问题来来回回困扰了我很久,一直没能妥善解决。场景1:华为手机遮挡了屏幕底部。场景2:进入应用时,虚拟键自动缩回,留下空白区域。需求:需要
- 混合事务在ORM框架的事务管理器的事务内,使用JdbcTemplate执行SQL是不会纳入事务管理的。下面进行源码分析,看为什么必须要在Da
- 之前的一篇文章中的代码中有一个using的用法,刚开始查看了一些资料说是强制关闭对象的一个命令。今天又查了一些资料,才明白,原来using指
- 寻找到application.yml的读取的操作。从spring.factories 中查看到# Application Listeners
- 这篇文章主要介绍了如何通过Java实现时间轴过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- 一、关于堆JDK1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础之上进行了一些元素的调
- 详解HDFS多文件Join操作的实例最近在做HDFS文件处理之时,遇到了多文件Join操作,其中包括:All Join以及常用的Left J
- 在 Android 中倒计时功能是比较常用的一个功能,比如短信验证码,付款倒计时等。实现方式有Handler、Thread 等,但是实现起来
- 问题用过storm或者jstorm的都知道,如果在bolt代码中发生了没被catch住的异常,所在worker进程会退出。本文就从源码角度分
- 程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间
- 1、线程的控制很常见,如文件传送到一半时,需要暂停文件传送,或终止文件传送,这实际上就是控制线程的运行。2、线程有创建、可运行、运行中、阻塞