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


猜你喜欢
- 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个。本算法利用62个可打印字符,通过随机
- 一、java调用post接口1、使用URLConnection或者HttpURLConnectionjava自带的,无需下载其他jar包UR
- 一、Java 运行时数据区域友情提示:这部分内容可能大部分同学都有一定的了解了,可以跳过直接进入下一小节哈。Java 虚拟机在执行 Java
- 在C#的网络编程中,进程和线程是必备的基础知识,同时也是一个重点,所以我们要好好的掌握一下。一:概念首先我们要知道什么是”进程”,什么是“线
- lambda表达式以及并行流。官方承诺你写出来的代码更运行得更快。流会自动通过Fork/Join池并行地执行。我听过一些关于Java 8的主
- 我们经常要将数字进行格式化,比如取2位小数,这是最常见的。Java 提供DecimalFormat类,帮你用最快的速度将数字格式化为你需要的
- 最近在研究JSON,Java中有很多处理JSON的类库,lib-json、sf-json、fastjson还有Jackson Json。第一
- 在说struts2的线程安全之前,先说一下,什么是线程安全?这是一个网友讲的。如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会
- 推送系统作为通用的组件,存在的价值主要有以下几点会被多个业务项目使用,推送系 * 立维护可降低维护成本推送系统一般都是调用三方api进行推送,
- 废话不多说了,直奔主题了。需要两个jar包:commons-fileupload.jarCommons IO的jar包(本文使用common
- 实现Runnable 接口比继承Thread 类的方式更好:(1)可以避免由于Java单继承带来的局限性;(2)可以实现业务执行逻辑和数据资
- 1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;2、Retent
- 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。下面是c#实现汉诺塔示例using System;using System
- 想要php版的朋友可以到这里下载测试 https://www.jb51.net/codes/83179.htmlimport java.io
- java中的JsonSerializer用法背景今天在写项目的时候遇到一个问题,项目中有个类中有创建时间和更新时间两个属性,但是单位在后端用
- 详解微信小程序 同步异步解决办法小程序中函数体还没有完成,下一个函数就开始执行了,而且两个函数之间需要传参。那是因为微信小程序函数是异步执行
- 对于大规模乱序的数组,插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点地从数组地一段移动到另一端。希尔排序改进了插入排序,交换不
- 我就废话不多说了,大家还是直接看代码吧~package com.zejian.annotationdemo; import java.lan
- springboot service内组件加载顺序先加载自身构造器,所以在构造器中初始化时若使用需要注入的(即@Autowired注解的)组
- 现如今打开一个 App,比如头条、微博,都会有长列表,随着我们不断地滑动,视窗内的内容也会不断地更新。今天就用 Flutter 实现一下这种