spring init

关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种:

第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作

第二种是:通过 在xml中定义init-method 和  destory-method方法

第三种是: 通过bean实现InitializingBean和 DisposableBean接口

 

 

在xml中配置 init-method和 destory-method方法

只是定义spring 容器在初始化bean 和容器销毁之前的所做的操作

基于xml的配置只是一种方式:

 

直接上xml中配置文件:

 

[html]  view plain copy
 
  1. <bean id="personService" class="com.myapp.core.beanscope.PersonService" scope="singleton"  init-method="init"  destroy-method="cleanUp">  
  2.   
  3. </bean>  

 

 

定义PersonService类:

 

[java]  view plain copy
 
  1. package com.myapp.core.beanscope;  
  2.   
  3.   
  4. public class PersonService  {  
  5.    private String  message;  
  6.   
  7.     public String getMessage() {  
  8.         return message;  
  9.     }  
  10.       
  11.     public void setMessage(String message) {  
  12.         this.message = message;  
  13.     }  
  14.      
  15.   
  16.       
  17.     public void init(){  
  18.         System.out.println("init");  
  19.     }  
  20.     //  how  validate the  destory method is  a question  
  21.     public void  cleanUp(){  
  22.         System.out.println("cleanUp");  
  23.     }  
  24. }  


相应的测试类:

 

 

[java]  view plain copy
 
  1. package com.myapp.core.beanscope;  
  2.   
  3. import org.springframework.context.support.AbstractApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class MainTest {  
  7.   public static void main(String[] args) {  
  8.         
  9.       AbstractApplicationContext  context =new  ClassPathXmlApplicationContext("SpringBeans.xml");  
  10.       
  11.     PersonService  person = (PersonService)context.getBean("personService");  
  12.       
  13.     person.setMessage("hello  spring");  
  14.       
  15.     PersonService  person_new = (PersonService)context.getBean("personService");  
  16.       
  17.     System.out.println(person.getMessage());  
  18.     System.out.println(person_new.getMessage());  
  19.     context.registerShutdownHook();  
  20.   
  21.       
  22. }  
  23. }   


测试结果:

 

init
hello  spring
hello  spring
cleanUp

可以看出 init 方法和 clean up方法都已经执行了。

 

context.registerShutdownHook(); 是一个钩子方法,当jvm关闭退出的时候会调用这个钩子方法,在设计模式之 模板模式中 通过在抽象类中定义这样的钩子方法由实现类进行实现,这里的实现类是AbstractApplicationContext,这是spring 容器优雅关闭的方法。

 

http://blog.youkuaiyun.com/topwqp/article/details/8681467

 

 

<think> 首先,用户的问题是:“我想查找spring init-method的实现方式 请问spring init-method的实现方式”。用户正在询问Spring框架中init-method的实现方式。 从系统级指令中,我需要: - 使用$...$格式的行内数学表达式(但这个问题是关于编程的,可能没有数学表达式,所以如果相关才用)。 - 独立公式用$$...$$,但可能不适用。 - 使用中文回答。 - 生成相关问题。 - 在引用段落末尾添加引用标识,如[^1]。 用户提供了几个引用: - [^1]:描述了init-method在构造函数后被调用,destroy-method在销毁前调用。 - [^2]:比较了init-method、@PostConstruct和InitializingBean。 - [^3]:展示了使用@Bean注解定义init和destroy方法。 - [^4]:讨论了执行顺序。 - [^5]:提到了一段代码,展示了如何在配置中设置init-method。 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 但在对话历史中,上一次问题是快速排序的演示,没有直接相关。这个对话是独立的,所以我会基于当前问题和引用回答。 关键点:用户想知道init-method的实现方式。这意味着Spring框架内部如何实现和调用init-method。 从引用中: - [^5]给出了一个线索:在解析配置时,如果有INIT_METHOD_ATTRIBUTE(init-method属性),就设置到BeanDefinition中。 我需要构建一个清晰的回答: 1. **解释init-method是什么**:init-method是Spring框架中允许在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-method在XML中? 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` 通过 XML 或 Java 配置声明,与 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 的执行顺序如何与其他钩子交互?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值