指定bean的初始化和销毁的四种方法
2018-07-09 本文已影响0人
缓慢移动的蜗牛
所使用的spring的版本为:4.3.12.RELEASE
一、使用@Bean时,指定initMethod和destroyMethod
package com.nanc.config;
import com.nanc.entity.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan({"com.nanc.entity"})
@PropertySource(value = {"classpath:/person.properties"})
public class MainConfig {
@Bean(initMethod = "init", destroyMethod = "destroy")
public Car car(){
return new Car();
}
}
实体类
package com.nanc.entity;
import java.io.Serializable;
public class Car implements Serializable {
private static final long serialVersionUID = 7710625002326921548L;
public Car() {
System.out.println("car constructor...");
}
public void init(){
System.out.println("car init...");
}
public void destroy(){
System.out.println("car destroy...");
}
}
person.properties文件
person.nickName=张三疯
二、让Bean实现InitializingBean(定义初始化逻辑)、DisposableBean(定义销毁逻辑)接口
实体bean的代码,采用注解的方式
package com.nanc.entity;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@Component
public class Cat implements Serializable, InitializingBean, DisposableBean {
private static final long serialVersionUID = -7379286171731060156L;
@Override
public void destroy() throws Exception {
System.out.println("cat destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat afterPropertiesSet...");
}
}
三、使用JSR250规范,@PostConstruct、@PreDestroy
@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
实体类
package com.nanc.entity;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.Serializable;
@Component
public class Dog implements Serializable {
private static final long serialVersionUID = 316697758215346823L;
public Dog() {
System.out.println("dog constructor...");
}
//对象创建并赋值之后调用
@PostConstruct
public void init(){
System.out.println("dog @PostConstruct....");
}
//容器移除对象之前
@PreDestroy
public void destroy(){
System.out.println("dog @PreDestroy...");
}
}
四、使用BeanPostProcessor接口(bean的后置处理器)
在bean初始化前后进行一些处理工作;
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
package com.nanc.entity;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 后置处理器,初始化前后进行处理工作
* 将后置处理器加入到容器中
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName+"---->"+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName+"---->"+bean);
return bean;
}
}
BeanPostProcessor在spring中的应用举例
向一个bean中注入ApplicationContext
package com.nanc.entity;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;
@Component
public class User implements ApplicationContextAware,EmbeddedValueResolverAware {
private ApplicationContext applicationContext;
private StringValueResolver resolver;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.resolver = resolver;
System.out.println("解析的值为:"+resolver.resolveStringValue("${person.nickName}"));
}
}
注入ApplicationContext,StringValueResolver的原因?
通过打断点可以,在spring的初始化流程中,调用了ApplicationContextAwareProcessor类中的postProcessBeforeInitialization(final Object bean, String beanName)方法
下面是相关的两个方法
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
测试代码
@Test
public void test(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Person person = applicationContext.getBean(Person.class);
System.out.println(person);
}
说明:可以在User类中的第16或22行打上断点,查看具体的调用栈信息
pom文件中的依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>