spring的生命周期(参考)
2016-04-01 22:48
274 查看
bean的完整生命周期 (十一步骤)【了解内容,但是对于spring内部操作理解有一定帮助】①instantiate bean对象实例化②populate properties 封装属性③如果Bean实现BeanNameAware 执行 setBeanName④如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext⑤如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization,BeanPostProcessor接口提供钩子函数,用来动态扩展修改Bean。(程序自动调用后处理Bean)
publicclassMyBeanPostProcessorimplementsBeanPostProcessor{
publicObject postProcessAfterInitialization(Object bean,String beanName)
throwsBeansException{
System.out.println("第八步:后处理Bean,after初始化。");
//后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
return bean;//返回bean,表示没有修改,如果使用动态代理,返回代理对象,那么就修改了。
}
publicObject postProcessBeforeInitialization(Object bean,String beanName)
throwsBeansException{
System.out.println("第五步:后处理Bean的:before初始化!!");
//后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
return bean;//返回bean本身,表示没有修改。
}
}注意:这个前处理Bean和后处理Bean会对所有的Bean进行拦截。⑥如果Bean实现InitializingBean 执行 afterPropertiesSet ⑦调用<bean init-method="init"> 指定初始化方法 init⑧如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization⑨执行业务处理⑩如果Bean实现 DisposableBean 执行 destroy⑪调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy* 为了能够比较清晰的看到上面的每一个步骤,我们模拟真实开发场景,定义一个接口和一个实现类
// 用户数据库操作
publicinterfaceUserDAO{
publicvoid add();
publicvoid search();
}实现类:
// 实现DAO 方法
publicclassUserDAOImplimplementsUserDAO,BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean{
privateString company;
publicUserDAOImpl(){
System.out.println("第一步 Bean的实例化 ...");
}
// 设置company
publicvoid setCompany(String company){
System.out.println("第二步 设置Bean的属性");
this.company = company;
}//如果实现了BeanNameAware接口,那么会将bean的那么设置到程序中,也就是userDao
publicvoid setBeanName(String beanName){
System.out.println("第三步 将xml配置Bean的name设置到程序中:"+ beanName);
// <bean id="userDAO"class="cn.itcast.spring.d_lifecycle.UserDAOImpl"></bean>
}
publicvoid setApplicationContext(ApplicationContext applicationContext)throwsBeansException{
System.out.println("第四步 将整合工厂上下文对象设置到 Bean中 ");
}
publicvoid afterPropertiesSet()throwsException{
System.out.println("第六步 属性设置完成后...");
}
publicvoid setup(){
System.out.println("第七步 配置初始化方法...init-method='setup'");
}//Bean初始化完毕,如果有业务方法,那么就开始执行,以下方法模拟业务方法。//这是在接口中定义的业务操作方法
publicvoid add(){
System.out.println("第九步 业务操作 .... 添加");
}//这是在接口中定义的业务操作方法
publicvoid search(){
System.out.println("第九步 业务操作 .... 查询");
}//destroy方法必须自己调用closed方法后才会执行。
publicvoid destroy()throwsException{
// 这个destroy无需配置,实现这个接口,就会自动的去调用destroy方法。
System.out.println("第十步 无需配置的销毁方法");
}
publicvoid teardown(){
System.out.println("第十一步 通过配置设置销毁方法...");
}
}其中少了第五步和第八步,此项内容在上面对应序号位置找。配置文件applicationContext.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入约束 来自xsd-config.html文件 -->
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">[/code]<beanid="userDAO"class="cn.itcast.spring.d_lifecycle.UserDAOImpl"init-method="setup"destroy-method="teardown"><!--第二步,设置bean的属性--><propertyname="company"value="itcast"></property></bean><!-- 必须配置后处理Bean , bean没有id 因为由 Spring框架内部调用 --><beanclass="cn.itcast.spring.d_lifecycle.MyBeanPostProccessor"></bean></beans>编写测试类:@Test// 测试Spring 生命周期publicvoid demo2(){ClassPathXmlApplicationContext applicationContext =newClassPathXmlApplicationContext("applicationContext.xml");UserDAO userDAO =(UserDAO) applicationContext.getBean("userDAO");//执行业务方法userDAO.add();userDAO.search();// 关闭工厂applicationContext.close();}运行结果: 分析: 前面前处理Bean和后处理Bean被执行多次,表示:钩子函数会对每个bean进行拦截(前面已经配置了其他的几个Bean,每个Bean都执行2次à前处理Bean后处理bean)。故而执行多次,反复连续的输出五,八。第三步和第四步,使我们写的Bean了解Spring容器 第五步和第八步,使用BeanPostProcessor 就是钩子函数,作用用来对Bean对象进行扩展。 问题: 在userDAO对象所有方法上 添加运行时间监控 【用后处理bean对目标bean在构造时进行代理,对原有方法进行扩展增强!】 我们可以利用后处理bean(BeanPostProcessor)与动态代理一起完成此功能,我们只需要在后处理bean的postProcessAfterInitialization方法里面改动代码即可/*** bean 就是对象实例 beanName 就是xml 配置Bean的id 或者 name*/publicObject postProcessAfterInitialization(finalObject bean,String beanName)throwsBeansException{System.out.println("第八步 执行后处理Bean 的初始化完成后方法...");if(beanName.equals("userDAO")){// 需要进行时间监控BeanObject proxy =Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(),newInvocationHandler(){publicObject invoke(Object proxy,Method method,Object[] args)throwsThrowable{if(method.getName().equals("search")){// 增强search方法System.out.println("开始时间:"+System.currentTimeMillis());Object result = method.invoke(bean, args);System.out.println("结束时间:"+System.currentTimeMillis());return result;}else{// 不加强return method.invoke(bean, args);}}});return proxy;}return bean;}运行测试结果: 我们发现:在业务方法search的前后环绕了增强的功能!
相关文章推荐
- Java 1.7 ReentrantLock源码解析
- Java Web 通过CKEditor实现在线编译器
- Java中对象与引用
- struts2配置基础和常见错误
- Java积累
- Java clone() 浅克隆与深度克隆
- 学习javaEE每一天2016.4.1
- Java编程思想篇
- eclipse下maven项目出现红色感叹号
- Eclipse或MyEclipse没有在java类文件上显示Spring图标的问题
- 深入java多态
- 关于Spring Security的笔记
- springboot-shiro chapter02——springboot webmvc jsp
- JavaSE学习笔记(2016.4.1)
- 27 API-反射(类的加载器,反射的使用,动态代理)&设计模式(装饰设计模式,模版设计模式)&JDK新特性(JDK5,JDK6,JDK7,DK8)
- Struts2中的Action
- Java集合类之栈Stack
- springmvc and maven
- 配置持久化框架diamond简介及高阶应用
- 配置持久化框架diamond简介及高阶应用