Spring init-method和destroy-method属性的使用

本文详细介绍了在Spring框架中利用init-method和destroy-method属性进行bean的初始化与销毁操作的方法,通过创建Speaker对象并配置相关属性,展示了如何在bean实例化时执行特定方法,并在bean销毁时执行另一特定方法。

知识点介绍:
有时候在bean初始化之后要执行的初始化方法,以及在bean销毁时执行的方法。这时就需要配置init-method和destroy-method属性,顾名思义,配置初始与销毁的方法。
【转载使用,请注明出处:http://blog.csdn.net/mahoking


操作步骤:
1、创建Speaker对象。

public class Speaker {

	private String name;
	private String topic;
	
	private Speaker(String name,String topic){
		this.name = name;
		this.topic = topic;
	}
	
	/**
	 * Speaker实例化时执行的方法
	 */
	private void init() {
		System.out.println("执行Speaker 的 初始化方法 init");
	}

	/**
	 * Speaker销毁时执行的方法
	 */
	private void destroy() {
		System.out.println("执行Speaker 的销毁方法 destroy");
	}
	
	public void teach() {
		
		System.out.println(toString());
	}
	
	@Override
	public String toString() {
		return "Speaker [name=" + name + ", topic=" + topic + "]";
	}
}

2、创建Spring配置文件beanLearn05.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- Learn 05 init-method和destroy-method属性的使用 -->
	<bean id="speaker05" class="com.mahaochen.spring.learn05.Speaker"
		init-method="init" destroy-method="destroy">
		<constructor-arg index="0" value="elle" />
		<constructor-arg index="1" value="Study Hard!" />
	</bean>
</beans>


3、将Spring配置文件beanLearn05.xml引入到主配置文件beans.xml中。

<!-- Learn 04  使用实例工厂方式实例化Bean -->
	<import resource="com/mahaochen/spring/learn05/beanLearn05.xml"/>


4、编写测试类TestSpring05.java。

public class TestSpring05 {

	public static void main(String[] args) {
		
		ApplicationContext appContext = new ClassPathXmlApplicationContext("beans.xml");
		Speaker speaker05 = (Speaker) appContext.getBean("speaker05");
		speaker05.teach();
		((ClassPathXmlApplicationContext) appContext).close();
	}
}


【转载使用,请注明出处:http://blog.csdn.net/mahoking

<think> 首先,用户的问题是:“我想查找spring init-method的实现方式 请问spring init-method的实现方式”。用户正在询问Spring框架中init-method的实现方式。 从系统级指令中,我需要: - 使用$...$格式的行内数学表达式(但这个问题是关于编程的,可能没有数学表达式,所以如果相关才用)。 - 独立公式用$$...$$,但可能不适用。 - 使用中文回答。 - 生成相关问题。 - 在引用段落末尾添加引用标识,如[^1]。 用户提供了几个引用: - [^1]:描述了init-method在构造函数后被调用,destroy-method在销毁前调用。 - [^2]:比较了init-method、@PostConstructInitializingBean。 - [^3]:展示了使用@Bean注解定义initdestroy方法。 - [^4]:讨论了执行顺序。 - [^5]:提到了一段代码,展示了如何在配置中设置init-method。 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题你的回答。” 但在对话历史中,上一次问题是快速排序的演示,没有直接相关。这个对话是独立的,所以我会基于当前问题引用回答。 关键点:用户想知道init-method的实现方式。这意味着Spring框架内部如何实现调用init-method。 从引用中: - [^5]给出了一个线索:在解析配置时,如果有INIT_METHOD_ATTRIBUTE(init-method属性),就设置到BeanDefinition中。 我需要构建一个清晰的回答: 1. **解释init-method是什么**:init-methodSpring框架中允许在Bean初始化后执行自定义方法的一种机制。 2. **实现方式**: -Spring的Bean生命周期中,当Bean实例化后,初始化阶段会调用指定的方法。 - 具体实现:在Spring的AbstractAutowireCapableBeanFactory类中,初始化时会检查BeanDefinition中是否有initMethodName设置。 - 如果设置了initMethodName,框架会通过反射调用该方法。 - 引用[^5]提到代码片段:在解析XML或配置时处理init-method属性。 3. **顺序与其他机制的对比**:引用[^4]提到执行顺序,可能需要简要提及,但焦点是实现方式。 4. **如何使用**:简要展示如何配置,如引用[^3]中的例子。 回答结构: - 开头解释init-method- 描述实现机制:Spring在Bean初始化阶段查找并调用指定的方法。 - 提及底层代码:如AbstractAutowireCapableBeanFactory中的initializeBean方法。 - 添加引用标识:在描述基于引用的内容时加[^n]。 - 生成相关问题。 确保语言是中文。 生成相关问题: - 类似于示例,如: 1. init-method@PostConstruct的区别是什么? 2. 如何配置init-methodXML中? 3. init-method的执行顺序如何控制? 最终回答: - 清晰、逐步解释。 - 结尾添加相关问题。 </think> ### Spring init-method 的实现方式 在 Spring 框架中,`init-method` 是一种用于指定 Bean 初始化后执行自定义逻辑的机制。它允许开发人员在 Bean 完全构造后(即构造函数调用完成后),通过配置式的方式触发一个特定的方法。这种方式解耦了 Bean 的初始化逻辑,使其更易于维护。以下我将逐步解释 `init-method` 的实现方式,基于 Spring 的内部机制提供的引用。 #### 1. **核心实现机制** Spring 在 Bean 的生命周期管理阶段实现 `init-method`,主要通过 BeanDefinition Bean 工厂类来处理: - **BeanDefinition 存储**:当 Spring 解析配置文件(如 XML)或注解时(如 `@Bean`),如果定义了 `init-method` 属性,它会将这个方法的名称存储到 BeanDefinition 对象中。这发生在配置加载阶段,例如在 XML 解析时: ```java // 类似引用[5]中的代码片段:解析 init-method 属性 if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) { String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE); if (!"".equals(initMethodName)) { bd.setInitMethodName(initMethodName); // 设置到 BeanDefinition } } ``` 这里,`INIT_METHOD_ATTRIBUTE` 对应配置中的 `init-method` 属性名,Spring 将其保存到 `bd`(BeanDefinition 实例)中[^5]。 - **初始化阶段调用**:在 Bean 实例化后,Spring 的核心类 `AbstractAutowireCapableBeanFactory` 负责初始化过程。具体在 `initializeBean` 方法中,它会检查 BeanDefinition 中是否有 `initMethodName`: - 如果设置了 `initMethodName`,Spring 通过 Java 反射机制调用该方法。 - 调用顺序在构造函数之后、依赖注入完成后,确保 Bean 处于有效状态[^1][^4]。 - 例如,伪代码简化: ```java protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) { // ... 其他初始化逻辑(如后置处理器) if (mbd.getInitMethodName() != null) { invokeCustomInitMethod(bean, mbd.getInitMethodName()); // 反射调用 init-method } return bean; } ``` #### 2. **与其他初始化机制的对比顺序** `init-method` 是 Spring 提供的多种初始化方式之一,与其他机制(如 `InitializingBean` 接口或 `@PostConstruct` 注解)共存: - **执行顺序**:根据引用[^4],Bean 初始化的标准顺序是: 1. 构造函数调用。 2. 依赖注入完成。 3. `@PostConstruct` 方法(如果使用了 JSR-250 注解)。 4. `InitializingBean` 的 `afterPropertiesSet` 方法。 5. 配置的 `init-method` 方法。 这意味着 `init-method` 总是在最后执行,确保所有前置初始化已完成[^2][^4]。 - **优势**:`init-method` 通过 XMLJava 配置声明,与 Bean 类解耦(不强制实现接口),提高了代码灵活性。相比 `@PostConstruct`(需要注解在方法上),它更适用于外部配置驱动的场景[^2][^3]。 #### 3. **配置示例** `init-method` 可以通过 XML 或注解配置: - **XML 配置**: ```xml <bean id="personBean" class="com.example.Person" init-method="init" destroy-method="destroy"/> ``` 这里,`init` 是 Person 类中定义的方法,Spring 在初始化后自动调用它[^3]。 - **注解配置**(使用 `@Bean`): ```java @Configuration public class AppConfig { @Bean(initMethod = "init", destroyMethod = "destroy") public Person person() { return new Person(); } } ``` 在 Person 类中定义 `public void init()` 方法作为初始化逻辑[^3]。 #### 4. **适用场景注意事项** - **典型用途**:加载初始化数据、资源连接(如数据库连接池启动)或状态验证,通常在构造函数后需要额外设置时使用[^3]。 - **注意事项**: - 方法必须是 public void 无参方法,否则 Spring 会抛出异常。 - 如果同时定义了多个初始化机制(如 `init-method` `@PostConstruct`),它们会按顺序执行,但推荐保持单一机制以避免复杂性[^4]。 - 销毁阶段的 `destroy-method` 实现类似,在 Bean 销毁前调用,处理资源释放[^1]。 总之,Spring `init-method` 的实现依赖于 BeanDefinition 存储方法反射调用,核心在 `AbstractAutowireCapableBeanFactory` 类中完成。这种机制设计灵活,是 Spring Bean 生命周期管理的重要组成部分[^1][^5]。 ### 相关问题 1. init-method @PostConstruct 的区别以及如何选择? 2. 如何在 Spring XML 配置中正确使用 init-method? 3. Spring Bean 的生命周期中,init-method 的执行顺序如何与其他钩子交互?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hoking

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值