在项目中经常会在容器启动时,完成特定的初始化操作,如资源文件的加载等。

一 实现的方式有三种:

1.使用@PostConstruct注解,该注解作用于void方法上

2.在配置文件中配置init-method方法

<bean id="student" class="com.demo.spring.entity.Student" init-method="init2">
<property name="name" value="景甜"></property>
<property name="age" value="28"></property>
<property name="school" ref="school"></property>
</bean>

3.将类实现InitializingBean接口

package com.demo.spring.entity;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component; /**
* @author chenyk
* @date 2018年5月8日
*/
@Component("student")
public class Student implements InitializingBean{
private String name;
private int age; private School school; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
} //1.使用postconstrtct注解
@PostConstruct
public void init(){
System.out.println("执行 init方法");
} //2.在xml配置文件中配置init-method方法
public void init2(){
System.out.println("执行init2方法 ");
} //3.实现InitializingBean接口
public void afterPropertiesSet() throws Exception {
System.out.println("执行init3方法");
} }

执行结果:

执行 init方法
2018-06-11 10:09:16,195 DEBUG [AbstractAutowireCapableBeanFactory.java:1671] : Invoking afterPropertiesSet() on bean with name 'student'
执行init3方法
2018-06-11 10:09:36,459 DEBUG [AbstractAutowireCapableBeanFactory.java:1731] : Invoking init method 'init2' on bean with name 'student'
执行init2 方法

二 实现原理:

由以上执行结果可知:先执行@PostConstruct注解的方法,然后是实现了InitializingBean接口的afterPropertiesSet方法,最后执行在配置文件中配置的init-method方法。至于为什么是这个顺序,可以看源码:

在 AbstractAutowireCapableBeanFactory 类中

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
} Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
} try {
       //调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

然后进入到 invokeInitMethods 方法中

    protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable { 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>() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
          //直接调用 InitializingBean 接口中的 afterPropertiesSet 方法
((InitializingBean) bean).afterPropertiesSet();
}
} if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
          //进入该方法可知通过反射的方式调用init-method方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}

所以,初始化方法的执行顺序 afterPropertiesSet() > init-method()

博客园的第一篇文章。感觉博客园很干净,文章排版特别是插入代码格式看起来很舒服。就不吐槽csdn了。

spring初始化bean时执行某些方法完成特定的初始化操作的更多相关文章

  1. ajax验证用户名 当用户名框的数据改变时 执行ajax方法

    ajax验证用户名 当用户名框的数据改变时 执行ajax方法 <html xmlns="http://www.w3.org/1999/xhtml" ><head ...

  2. 计算属性 vs 侦听属性 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的

    https://cn.vuejs.org/v2/guide/computed.html#基础例子 计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属 ...

  3. Spring 为Bean对象执行初始化和销毁方法

    1)初始化: ①可以利用<bean>元素的init-method="方法名"属性指定初始化方法. ②指定的初始化方法是在构造方法调用后自动执行.若非单例模式,则每创建一 ...

  4. Spring项目启动时执行初始化方法

    一.applicationContext.xml配置bean <bean id="sensitiveWordInitUtil" class ="com.hx.daz ...

  5. spring注解之@PostConstruct在项目启动时执行指定方法

    一.注解解释 Spring的@PostConstruct注解在方法上,表示此方法是在Spring实例化该Bean之后马上执行此方法,之后才会去实例化其他Bean,并且一个Bean中@PostConst ...

  6. 当spring 容器初始化完成后执行某个方法

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  7. 当spring 容器初始化完成后执行某个方法 防止onApplicationEvent方法被执行两次

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  8. Spring的Bean的生命周期方法执行顺序测试

    通过一个简单的Maven工程来演示Spring的Bean生命周期函数的执行顺序. 下面是工程的目录结构: 直接贴代码: pom.xml文件内容: <?xml version="1.0& ...

  9. Spring中Bean的生命周期方法

    Bean的生命周期方法 src\dayday\Car.java package dayday;import com.sun.org.apache.xpath.internal.SourceTree;i ...

随机推荐

  1. Django-rest-framework 接口实现 权限:(Permission)

    权限:(Permission) rest_framework 中 已经定义好了 权限 在 from rest_framework.permissions 中查看所有的权限 from rest_fram ...

  2. tensorflow错误:Shape (10, ?) must have rank at least 3

    错误的代码 outputs, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32) 错误原因: 该错误的意思是传入的数据集X的维度只有二维,而tf.nn.d ...

  3. C# Lambda 表达式学习之(四):动态构建类似于 c => c.Age == 2 || c.Age == 5 || c => c.Age == 17 等等一个或多个 OrElse 的表达式

    可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...

  4. VMware15安装MAC(MAC OS 10.13)(OS X 10.14)原版可升级最新可解锁macOS Unlocker3.0(OS X 10.13)

      目录树 1.1.2安装环境: 1.1.3所需资源: 1.1.4 Unlocker 3.0解锁 1.1.5 配置环境 1.1.6开始安装 1.1.7开启虚拟机进入MAC安装界面 1.1.8 macO ...

  5. 基于SpringBoot的项目管理后台

    代码地址如下:http://www.demodashi.com/demo/13943.html 一.项目简介 在使用本项目之前,需要对SpringBoot,freemaker,layui,flyway ...

  6. P1145 约瑟夫 W(模拟)

    暴力+模拟 #include<iostream> #include<cstring> using namespace std; int ans, k, k2; ]; bool ...

  7. @ModelAttribute

    在执行Controller方法前都会新建一个Map对象称为隐含模型,该Map对象是共享的,如果一个方法的入参为Map ModelAndMap ModelMap等类型,那么会把隐含模型当做入参赋给方法. ...

  8. day95

    Linux基本部署配置及常见扩展应用 Linux软件包安装方法 1. 安装: 整个安装过程可以分为以下几步: 1) 取得应用软件:通过下载.购买光盘的方法获得: 2)解压缩文件:一般tar包,都会再做 ...

  9. 【原创】jssh linux scp ssh 免密登录开源工具

    项目名 JSSH git地址: https://gitee.com/chejiangyi/jssh 项目介绍 linux scp(文件上传,下载) shell命令的java ssh jar和linux ...

  10. iOS开发之CoreImage

    CoreImage是iOS中的一个图像处理框架,提供了强大高效的图像处理功能,可以通过调用简单的API来使用框架所带的各种滤镜对图像进行处理. CoreImgae的三个重要组成部分:1.CIFiter ...