spring的生命周期(参考)

bean的完整生命周期 (十一步骤)【了解内容,但是对于spring内部操作理解有一定帮助

instantiate bean对象实例化

populate properties 封装属性

如果Bean实现BeanNameAware 执行 setBeanName

如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext

如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization,BeanPostProcessor接口提供钩子函数,用来动态扩展修改Bean(程序自动调用后处理Bean)

  
  
  1. publicclassMyBeanPostProcessorimplementsBeanPostProcessor{
  2. publicObject postProcessAfterInitialization(Object bean,String beanName)
  3. throwsBeansException{
  4. System.out.println("第八步:后处理Bean,after初始化。");
  5. //后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
  6. return bean;//返回bean,表示没有修改,如果使用动态代理,返回代理对象,那么就修改了。
  7. }
  8. publicObject postProcessBeforeInitialization(Object bean,String beanName)
  9. throwsBeansException{
  10. System.out.println("第五步:后处理Bean的:before初始化!!");
  11. //后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
  12. return bean;//返回bean本身,表示没有修改。
  13. }
  14. }
  15. 注意:这个前处理Bean和后处理Bean会对所有的Bean进行拦截。
如果 Bean 实现 InitializingBean  执行  afterPropertiesSet 

调用<bean init-method="init"> 指定初始化方法 init

如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization

执行业务处理

如果Bean实现 DisposableBean 执行 destroy

调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy


* 为了能够比较清晰的看到上面的每一个步骤,我们模拟真实开发场景,定义一个接口和一个实现类

  
  
  1. // 用户数据库操作
  2. publicinterfaceUserDAO{
  3. publicvoid add();
  4. publicvoid search();
  5. }
实现类:
   
   
  1. // 实现DAO 方法
  2. publicclassUserDAOImplimplementsUserDAO,BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean{
  3. privateString company;
  4. publicUserDAOImpl(){
  5. System.out.println("第一步 Bean的实例化 ...");
  6. }
  7. // 设置company
  8. publicvoid setCompany(String company){
  9. System.out.println("第二步 设置Bean的属性");
  10. this.company = company;
  11. }
  12. //如果实现了BeanNameAware接口,那么会将bean的那么设置到程序中,也就是userDao
  13. publicvoid setBeanName(String beanName){
  14. System.out.println("第三步 将xml配置Bean的name设置到程序中:"+ beanName);
  15. // <bean id="userDAO" class="cn.itcast.spring.d_lifecycle.UserDAOImpl"></bean>
  16. }
  17. publicvoid setApplicationContext(ApplicationContext applicationContext)throwsBeansException{
  18. System.out.println("第四步 将整合工厂上下文对象设置到 Bean中 ");
  19. }
  20. publicvoid afterPropertiesSet()throwsException{
  21. System.out.println("第六步 属性设置完成后...");
  22. }
  23. publicvoid setup(){
  24. System.out.println("第七步 配置初始化方法...init-method='setup'");
  25. }
  26. //Bean初始化完毕,如果有业务方法,那么就开始执行,以下方法模拟业务方法。

  27. //这是在接口中定义的业务操作方法
  28. publicvoid add(){
  29. System.out.println("第九步 业务操作 .... 添加");
  30. }
  31. //这是在接口中定义的业务操作方法
  32. publicvoid search(){
  33. System.out.println("第九步 业务操作 .... 查询");
  34. }
  35. //destroy方法必须自己调用closed方法后才会执行。
  36. publicvoid destroy()throwsException{
  37. // 这个destroy无需配置,实现这个接口,就会自动的去调用destroy方法。
  38. System.out.println("第十步 无需配置的销毁方法");
  39. }
  40. publicvoid teardown(){
  41. System.out.println("第十一步 通过配置设置销毁方法...");
  42. }
  43. }
其中少了第五步和第八步,此项内容在上面对应序号位置找。

配置文件applicationContext.cfg.xml:

  
  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- 引入约束 来自xsd-config.html文件 -->
  3. <beansxmlns="http://www.springframework.org/schema/beans"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="
  7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  8. <beanid="userDAO"class="cn.itcast.spring.d_lifecycle.UserDAOImpl"init-method="setup"destroy-method="teardown">
  9. <!--第二步,设置bean的属性-->
  10. <propertyname="company"value="itcast"></property>
  11. </bean>
  12. <!-- 必须配置后处理Bean , bean没有id 因为由 Spring框架内部调用 -->
  13. <beanclass="cn.itcast.spring.d_lifecycle.MyBeanPostProccessor"></bean>
  14. </beans>
编写测试类:
   
   
  1. @Test
  2. // 测试Spring 生命周期
  3. publicvoid demo2(){
  4.     ClassPathXmlApplicationContext applicationContext =newClassPathXmlApplicationContext("applicationContext.xml");
  5.     UserDAO userDAO =(UserDAO) applicationContext.getBean("userDAO");
  6. //执行业务方法
  7.     userDAO.add();
  8.     userDAO.search();
  9.     // 关闭工厂
  10.     applicationContext.close();
  11. }
运行结果:

    

分析:

    前面前处理Bean和后处理Bean被执行多次,表示:钩子函数会对每个bean进行拦截(前面已经配置了其他的几个Bean,每个Bean都执行2à前处理Bean后处理bean)故而执行多次,反复连续的输出五,八。

第三步和第四步,使我们写的Bean了解Spring容器 

第五步和第八步,使用BeanPostProcessor 就是钩子函数,作用用来对Bean对象进行扩展。

 

问题: 在userDAO对象所有方法上 添加运行时间监控  【用后处理bean对目标bean在构造时进行代理,对原有方法进行扩展增强!

    我们可以利用后处理bean(BeanPostProcessor)与动态代理一起完成此功能,我们只需要在后处理bean的postProcessAfterInitialization方法里面改动代码即可

  
  
  1. /**
  2. * bean 就是对象实例 beanName 就是xml 配置Bean的id 或者 name
  3. */
  4. publicObject postProcessAfterInitialization(finalObject bean,String beanName)throwsBeansException{
  5.     System.out.println("第八步 执行后处理Bean 的初始化完成后方法...");
  6. if(beanName.equals("userDAO")){
  7.     // 需要进行时间监控Bean
  8. Object proxy =Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(),newInvocationHandler(){
  9.     publicObject invoke(Object proxy,Method method,Object[] args)throwsThrowable{
  10.     if(method.getName().equals("search")){
  11.     // 增强search方法
  12. System.out.println("开始时间:"+System.currentTimeMillis());
  13. Object result = method.invoke(bean, args);
  14. System.out.println("结束时间:"+System.currentTimeMillis());
  15. return result;
  16. }else{
  17. // 不加强
  18. return method.invoke(bean, args);
  19. }
  20. }
  21. });
  22. return proxy;
  23.     }
  24. return bean;
  25. }
运行测试结果:
    
我们发现:在业务方法search的前后环绕了增强的功能!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值