Spring 之 生命周期机制混合使用

对于同一个bean,有多种生命周期机制,其有不同的初始化方法,如下所示:

 

1        使用@PostConstruct注解的方法

2    实现了InitializingBean回调接口,并定义了afterPropertiesSet()方法

3    自定义的init()方法

 

销毁方法如下顺序:

1          @PreDestory注解的方法

2    DisposableBean回调接口定义的destroy()方法

3    自定义的destroy()方法

 

4.6.1.5 启动和关闭回调

   Lifecycle接口定义了每个对象的重要方法,每个对象都有自己的生命周期需求,如下:


public interface Lifecycle {

  void start();

  void stop();

  boolean isRunning();

}


任何Spring管理的对象可能实现这个接口。那么,当ApplicationContext自身启动和停止时,它将自动调用上下文内所有生命周期的实现。通过委托给LifecycleProcessor来做这个工作。

 

public interface LifecycleProcessor extends Lifecycle {

  void onRefresh();

  void onClose();

}


注意LifecycleProcessor自身扩展了Lifecycle接口。它也增加了两个其他的方法来与上下文交互,使得可以刷新和关闭。

 

启动和关闭调用的顺序是很重要的。如果两个对象之间存在依赖关系,依赖类要在其依赖类后启动,依赖类也要在其依赖类前停止。然而,有时候其之间的依赖关系不是那么直接。你可能仅仅知道某种类型的对象应该在另一类型对象前启动。在那些情况下,SmartLifecycle接口定义了另一个选项,在其父类接口Phased中定义命名为getPhase()方法。



public interface Phased {

  int getPhase();

}


public interface SmartLifecycle extends Lifecycle, Phased {

  boolean isAutoStartup();

  void stop(Runnable callback);

}


当启动时,有最低phase的对象首先启动,并且停止时,按照相反的顺序结束。因此,实现了SmartLifecycle接口并且其getPhase()方法返回Integer.MIN_VALUE的一个对象将是首先被启动并且最后停止。与其相反对应的对象,Integer.MAX_VALUE的phase的值,将指明最后启动和最先停止(可能是其依赖其他对象工作运行)。当考虑phase值时,了解任何普通Lifecycle对象(没有实现SmartLifecycle其值将是0)的默认phase也很重要。因此,任何负数phase值将表示对象应该在那些标准组件前启动(并其之后停止),并且对于正数的phase值按照相反顺序启动停止。

 

 

如你在SmartLifecycle接口中定义的stop方法内有一回调参数。任何实现类在其关闭完成后必须调用回调的run方法。必须的时候由于实现了LifecycleProcessor接口的实现类可以进行异步关闭操作,DefaultLifecycleProcessor,对于在每个phase调用那个回调内的对象组将等待一个超时时间。默认的每个phase的超时是30秒。你可以通过在上下文内定义一个命名为lifecycleProcessor的bean重写默认的生命周期处理器实例。如果你仅仅想修改超时时间,如下定义将会很有用:



<bean id="lifecycleProcessor"class="org.springframework.context.support.DefaultLifecycleProcessor">
  <!-- timeout value in milliseconds -->
  <property name="timeoutPerShutdownPhase" value="10000"/>
</bean>


LifecycleProcessor接口定义了回调方法来刷新和关闭上下文。后者仅简单地做关闭处理如同直接地调用stop方法,但是当关闭上下文时,这将起作用。刷新回调使得SmartLifecycle bean的另一个功能起作用。当上下文刷新时(在所有的对象实例化和初始化后),将调用那个回调,并且在那个点上,默认的生命周期处理器将检查每个SmartLifecycle对象的isAutoStartup()方法的返回值。如果是true,那么对象将在那个点上启动而不是等一个上下文的明确调用或者等其自己的start()方法(不像上下文的刷新,上下文启动对于标准的上下文实现不是自动发生的)phase值与依赖关系一样将如上所述决定了启动顺序。

 

 

4.6.1.6  在非web应用程序中关闭Spring IoC容器

 

注意:这一章节仅仅适用非web应用程序。Spring基于web的ApplicationContext实现已经有代码来关闭Spring IoC容器,当有关的web应用关闭时。

 

 

如果使用SpringIoC容器在非web应用环境中,例如,在富客户端的桌面环境中;你使用JVM注册一个shutdown钩子。这样做保证了优雅地关闭并在你的singletonbeans调用相关的destory方法,这样可以释放所有的资源。当然了,你仍旧必须正确地配置和实现这些销毁对调方法。

 

 

为注册一个shutdown钩子,你调用registerShutdownHook()方法,其在AbstractApplicationContext类中声明如下。

 


import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class Boot {

  public static void main(final String[] args) throws Exception {
      AbstractApplicationContext ctx
          = new ClassPathXmlApplicationContext(new String []{"beans.xml"});

      // add a shutdown hook for the above context... 
      ctx.registerShutdownHook();

      // app runs here...

      // main method exits, hook is called prior to the app shutting down...
  }
}



4.6.2  ApplicationContextAware和BeanNameAware

 

 

当一个ApplicationContext创建了一个类,其实现了org.springframework.context.ApplicationContextAware接口,这类提供了那个ApplicationContext的一个引用。



public interface ApplicationContextAware {

  void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

那么bean可以程序化的操作ApplicationContext(创建了这些beans),通过了ApplicationContext接口,或者将这个引用转化为这个接口的子类,比如ConfigurableApplicationContext,其暴露了更多的功能。一种方法是用来其他beans的程序化检索。有时候这种用法很有用,然而,一般避免这样使用。因为这样的话就与Spring代码耦合了并且不遵循IoC类型,这里依赖以属性提供给beans。ApplicationContext的其他方法提供访问文件资源的功能,发布应用事件,并访问消息资源。

 

 

 

在Spring2.5中,autowiring是获取ApplicationContext引用的另一种可选方式。传统的constructor和byType autowiring模式可以提供分别为构造器参数或者setter方法参数的ApplicationContext类型的依赖。为了更加灵活,包含了autowiring 字段和多参数方法的能力,使用基于注解的autowiring功能。如果你做了,ApplicationContext自动包装为一个字段,构造器参数,或者方法的参数,类型为BeanFactory类型,如果字段,构造器或者方法使用了@Autowired注解。

 

 

当ApplicationContext创建了一个类,其实现了org.springframework.beans.factory.BeanNameAware接口,这个类提供了一个引用,其名字在相关联的对象定义中定义。


public interface BeanNameAware {

  void setBeanName(string name) throws BeansException;
}


在普通的bean属性设置后但是在初始化回调前(比如InitializingBeans的afterPropertiesSet或者自定义的init-method)调用回调。



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值