您的位置:首页 > 编程语言 > Java开发

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

2016-04-06 23:34 489 查看
对于同一个bean,有多种生命周期机制,其有不同的初始化方法,如下所示:

1使用@PostConstruct注解的方法

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


3
自定义的init()方法


销毁方法如下顺序:

1@PreDestory注解的方法

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


3
自定义的destroy()方法


4.6.1.5启动和关闭回调

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

[java]view
plaincopy

publicinterfaceLifecycle{

voidstart();

voidstop();

booleanisRunning();

}

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




[java]view
plaincopy

publicinterfaceLifecycleProcessorextendsLifecycle{

voidonRefresh();

voidonClose();

}

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



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


[java]view
plaincopy

publicinterfacePhased{

intgetPhase();

}

publicinterfaceSmartLifecycleextendsLifecycle,Phased{

booleanisAutoStartup();

voidstop(Runnablecallback);

}

当启动时,有最低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重写默认的生命周期处理器实例。如果你仅仅想修改超时时间,如下定义将会很有用:

[html]view
plaincopy

<beanid="lifecycleProcessor"class="org.springframework.context.support.DefaultLifecycleProcessor">

<!--timeoutvalueinmilliseconds-->

<propertyname="timeoutPerShutdownPhase"value="10000"/>

</bean>

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






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




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






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

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




[java]view
plaincopy

importorg.springframework.context.support.AbstractApplicationContext;

importorg.springframework.context.support.ClassPathXmlApplicationContext;

publicfinalclassBoot{

publicstaticvoidmain(finalString[]args)throwsException{

AbstractApplicationContextctx

=newClassPathXmlApplicationContext(newString[]{"beans.xml"});

//addashutdownhookfortheabovecontext...

ctx.registerShutdownHook();

//apprunshere...

//mainmethodexits,hookiscalledpriortotheappshuttingdown...

}

}

4.6.2ApplicationContextAware
和BeanNameAware





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


[java]view
plaincopy

publicinterfaceApplicationContextAware{

voidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException;

}

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

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






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


[java]view
plaincopy

publicinterfaceBeanNameAware{

voidsetBeanName(stringname)throwsBeansException;

}

在普通的bean属性设置后但是在初始化回调前(比如
InitializingBean
s的afterPropertiesSet或者自定义的init-method)调用回调。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: