Spring核心接口之InitializingBean
一、InitializingBean接口说明
InitializingBean接口为bean提供了属性初始化后的处理方法,它只包括afterPropertiesSet方法,凡是继承该接口的类,在bean的属性初始化后都会执行该方法。
package org.springframework.beans.factory;
/**
* Interface to be implemented by beans that need to react once all their
* properties have been set by a BeanFactory: for example, to perform custom
* initialization, or merely to check that all mandatory properties have been set.
*
* <p>An alternative to implementing InitializingBean is specifying a custom
* init-method, for example in an XML bean definition.
* For a list of all bean lifecycle methods, see the BeanFactory javadocs.
*
* @author Rod Johnson
* @see BeanNameAware
* @see BeanFactoryAware
* @see BeanFactory
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.context.ApplicationContextAware
*/
public interface InitializingBean {
/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception;
}
从方法名afterPropertiesSet也可以清楚的理解该方法是在属性设置后才调用的。
二、源码分析接口应用
通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可以看到
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) { //判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method
String initMethodName = mbd.getInitMethodName();
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指定的方法。
三、接口应用
InitializingBean接口在spring框架中本身就很多应用,这就不多说了。我们在实际应用中如何使用该接口呢?
1、使用InitializingBean接口处理一个配置文件:
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import org.springframework.beans.factory.InitializingBean;
public class ConfigBean implements InitializingBean{
//微信公众号配置文件
private String configFile;
private String appid;
private String appsecret;
public String getConfigFile() {
return configFile;
}
public void setConfigFile(String configFile) {
this.configFile = configFile;
}
public void afterPropertiesSet() throws Exception {
if(configFile!=null){
File cf = new File(configFile);
if(cf.exists()){
Properties pro = new Properties();
pro.load(new FileInputStream(cf));
appid = pro.getProperty("wechat.appid");
appsecret = pro.getProperty("wechat.appsecret");
}
}
System.out.println(appid);
System.out.println(appsecret);
}
}
2、配置
spring配置文件:
<bean id="configBean" class="com.ConfigBean">
<property name="configFile" value="d:/wechat.properties"></property>
</bean>
wechat.properties配置文件
wechat.appid=wxappid
wechat.appsecret=wxappsecret
3、测试
public static void main(String[] args) throws Exception {
String config = Test.class.getPackage().getName().replace('.', '/') + "/bean.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
context.start();
}
喜欢就关注我
Spring核心接口之InitializingBean的更多相关文章
- spring 核心接口之 Ordered
Spring中提供了一个Ordered接口.从单词意思就知道Ordered接口的作用就是用来排序的.Spring框架是一个大量使用策略设计模式的框架,这意味着有很多相同接口的实现类,那么必定会有优先级 ...
- 一文带你了解Spring核心接口Ordered的实现及应用
前言 最近在看框架的时候,发现了这个接口,在此进行总结,希望能够给大家帮助,同时提升自己. order接口的大体介绍 Spring框架中有这个一个接口,名字叫Ordered,联想我们在数据库中应用的O ...
- spring中基础核心接口总结
spring中基础核心接口总结理解这几个接口,及其实现类就可以快速了解spring,具体的用法参考其他spring资料 1.BeanFactory最基础最核心的接口重要的实现类有:XmlBeanFac ...
- Spring Boot REST(一)核心接口
Spring Boot REST(一)核心接口 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) SpringBoot RE ...
- spring常用接口 InitializingBean的作用
工作中遇到spring接口中的InitializingBean接口.浅浅的解说一下. --------------------------------------------------------- ...
- spring 的核心接口
spring有两个核心接口,BeanFactory 和ApplicationContext ,其中ApplicationContext 是BeanFactory的子接口.他们代表了Spring容器. ...
- 【Spring】Spring的事务管理 - 1、Spring事务管理概述(数据库事务、Spring事务管理的核心接口)
Spring事务管理概述 文章目录 Spring事务管理概述 数据库事务 什么是Spring的事务管理? Spring对事务管理的支持 Spring事务管理的核心接口 Platform Transac ...
- Spring核心——Bean的定义与控制
在Sring核心与设计模式的文章中,分别介绍了Ioc容器和Bean的依赖关系.如果阅读过前2文就会知道,Spring的整个运转机制就是围绕着IoC容器以及Bean展开的.IoC就是一个篮子,所有的Be ...
- 初识Spring——Spring核心容器
一. IOC和DI基础 IOC-Inversion of Control,译为控制反转,是一种遵循依赖倒置原则的代码设计思想. 所谓依赖倒置,就是把原本的高层建筑依赖底层建筑“倒置”过来,变成底层建筑 ...
随机推荐
- 剑指offer第二版面试题9:用两个队列实现栈(JAVA版)
题目:用两个队列实现栈. 分析:通过一系列的栈的压入和弹出操作来分析用队列模拟一个栈的过程,如图所示,我们先往栈内压入一个元素a.由于两个队列现在都是空,我们可以选择把a插入两个队列中的任一个.我们不 ...
- maven surefire入门
一.maven常用命令: mvn compile mvn install mvn test mvn clean mvn dependency:resolve -X #查看完整的debug信息!!! ...
- 序列化之 TLV
目录 序列化之 TLV 1. 紧凑模式 2. 可扩展性 3. 更好的可扩展性 4. 自解释性 5. 跨语言特性 6. 代码自动化:IDL语言 7. 总结 序列化之 TLV 通信协议可以理解两个节点之间 ...
- USACO2007 The Bale Tower /// DFS oj21160
题目大意: 给出N个捆包,每个捆包有相应的长度和宽度,要求堆叠捆包,使下方的捆包长宽永远大于上方的捆包的长宽. Input Multiple test case. For each case: * L ...
- async / await对异步的处理
虽然co是社区里面的优秀异步解决方案,但是并不是语言标准,只是一个过渡方案.ES7语言层面提供async / await去解决语言层面的难题.目前async / await 在 IE edge中已经可 ...
- jeecg Online表单开发中新增自定义按钮
要求:给表单增加一个“确认”按钮,按钮功能更改选中数据的flag字段为1 点击“自定义按钮”,录入一个“确认”按钮 按钮编码:该编码在一个智能表单配置中唯一,该编码同时是按钮触发的JS函数名.例如:按 ...
- QT 环境变量配置
//注意每个人的习惯不一样 在系统变量中新建: { QT = C:\Qt\Qt5.13.1\5.13.1 QT_TOOL = C:\Qt\Qt5.13.1\Tools } 然后在path 中加入 { ...
- 2018阿里云云数据库RDS核心能力演进
摘要: 2018年云数据库RDS发展上,不但针对MySQL.SQL Server.PostgreSQL提供了适合个人入门用户的基础版产品,以实惠的价格普惠广大中小用户.更加入最新的MariaDB TX ...
- BZOJ 1415: [Noi2005]聪聪和可可(记忆化搜索+期望)
传送门 解题思路 还是比较简答的一道题.首先\(bfs\)把每个点到其他点的最短路求出来,然后再记忆化搜索.记搜的时候猫的走法是确定的,搜一下老鼠走法就行了. 代码 #include<iostr ...
- MTT:任意模数NTT
MTT:任意模数NTT 概述 有时我们用FFT处理的数据很大,而模数可以分解为\(a\cdot 2^k+1\)的形式.次数用FFT精度不够,用NTT又找不到足够大的模数,于是MTT就应运而生了. MT ...