spring中bean的生命周期

来源:互联网 发布:php抽象类和接口的作用 编辑:程序博客网 时间:2024/06/11 04:57
1 生命周期
 
1.1 初始化和销毁
目标方法执行前后执行后,将进行初始化或销毁。
<bean id="" class="" init-method="初始化方法名称"  destroy-method="销毁的方法名称">


1.1.1 目标类
public class UserServiceImpl implements UserService {


@Override
public void addUser() {
System.out.println("e_lifecycle add user");
}

public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}


}


1.1.2 spring配置
<!--  
init-method 用于配置初始化方法,准备数据等
destroy-method 用于配置销毁方法,清理资源等
-->
<bean id="userServiceId" class="com.itheima.e_lifecycle.UserServiceImpl" 
init-method="myInit" destroy-method="myDestroy" ></bean>


1.1.3 测试
@Test
public void demo02() throws Exception{
//spring 工厂
String xmlPath = "com/itheima/e_lifecycle/beans.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();

//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
applicationContext.close();

}


1.1.4 BeanPostProcessor 后处理Bean
spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置<bean class="">
 
Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies. 
spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。
模拟
A a =new A();
a = B.before(a) --> 将a的实例对象传递给后处理bean,可以生成代理对象并返回。
a.init();
a = B.after(a);


a.addUser(); //生成代理对象,目的在目标方法前后执行(例如:开启事务、提交事务)


a.destroy()


1.1.5 编写实现类
public class MyBeanPostProcessor implements BeanPostProcessor {


@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("前方法 : " + beanName);
return bean;
}


@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("后方法 : " + beanName);
// bean 目标对象
// 生成 jdk 代理
return Proxy.newProxyInstance(
MyBeanPostProcessor.class.getClassLoader(), 
bean.getClass().getInterfaces(), 
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("------开启事务");

//执行目标方法
Object obj = method.invoke(bean, args);

System.out.println("------提交事务");
return obj;
}});
}
}


1.1.6 配置
<!-- 将后处理的实现类注册给spring -->
<bean class="com.itheima.e_lifecycle.MyBeanPostProcessor"></bean>


问题1:后处理bean作用某一个目标类,还是所有目标类?
所有
问题2:如何只作用一个?
通过“参数2”beanName进行控制