解@PostConstruct与@PreDestroy注解

注解@PostConstruct与@PreDestroy讲解及实例
从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 。写法有如下两种方式:
@PostConstruct
Public void someMethod() {}

或者
public @PostConstruct void someMethod(){}
被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。PreDestroy()方法在destroy()方法执行执行之后执行

javax.annotation
Annotation Type PostConstruct


@Documented
@Retention(value=RUNTIME)
@Target(value=METHOD)
public @interface PostConstruct
The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection. The method annotated with PostConstruct MUST be invoked even if the class does not request any resources to be injected. Only one method can be annotated with this annotation. The method on which the PostConstruct annotation is applied MUST fulfill all of the following criteria:
The method MUST NOT have any parameters except in the case of interceptors in which case it takes an InvocationContext object as defined by the Interceptors specification.
The method defined on an interceptor class MUST HAVE one of the following signatures:
void <METHOD>(InvocationContext)

Object <METHOD>(InvocationContext) throws Exception

Note: A PostConstruct interceptor method must not throw application exceptions, but it may be declared to throw checked exceptions including the java.lang.Exception if the same interceptor method interposes on business or timeout methods in addition to lifecycle events. If a PostConstruct interceptor method returns a value, it is ignored by the container.

The method defined on a non-interceptor class MUST HAVE the following signature:
void <METHOD>()

The method on which PostConstruct is applied MAY be public, protected, package private or private.
The method MUST NOT be static except for the application client.
The method MAY be final.
If the method throws an unchecked exception the class MUST NOT be put into service except in the case of EJBs where the EJB can handle exceptions and even recover from them.
Since:
Common Annotations 1.0
See Also:
PreDestroy, Resource


Annotation Type PreDestroy


@Documented
@Retention(value=RUNTIME)
@Target(value=METHOD)
public @interface PreDestroy
The PreDestroy annotation is used on methods as a callback notification to signal that the instance is in the process of being removed by the container. The method annotated with PreDestroy is typically used to release resources that it has been holding. This annotation MUST be supported by all container managed objects that support PostConstruct except the application client container in Java EE 5. The method on which the PreDestroy annotation is applied MUST fulfill all of the following criteria:
The method MUST NOT have any parameters except in the case of interceptors in which case it takes an InvocationContext object as defined by the Interceptors specification.
The method defined on an interceptor class MUST HAVE one of the following signatures:
void <METHOD>(InvocationContext)

Object <METHOD>(InvocationContext) throws Exception

Note: A PreDestroy interceptor method must not throw application exceptions, but it may be declared to throw checked exceptions including the java.lang.Exception if the same interceptor method interposes on business or timeout methods in addition to lifecycle events. If a PreDestroy interceptor method returns a value, it is ignored by the container.

The method defined on a non-interceptor class MUST HAVE the following signature:
void <METHOD>()

The method on which PreDestroy is applied MAY be public, protected, package private or private.
The method MUST NOT be static.
The method MAY be final.
If the method throws an unchecked exception it is ignored except in the case of EJBs where the EJB can handle exceptions.
Since:
Common Annotations 1.0
See Also:
PostConstruct, Resource

API使用说明
以下为@PostConstruct的API使用说明:
PostConstruct 注释用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。此方法必须在将类放入服务之前调用。支持依赖关系注入的所有类都必须支持此注释。即使类没有请求注入任何资源,用 PostConstruct 注释的方法也必须被调用。只有一个方法可以用此注释进行注释。应用 PostConstruct 注释的方法必须遵守以下所有标准:该方法不得有任何参数,除非是在 EJB 拦截器 (interceptor) 的情况下,根据 EJB 规范的定义,在这种情况下它将带有一个 InvocationContext 对象 ;该方法的返回类型必须为 void;该方法不得抛出已检查异常;应用 PostConstruct 的方法可以是 public、protected、package private 或 private;除了应用程序客户端之外,该方法不能是 static;该方法可以是 final;如果该方法抛出未检查异常,那么不得将类放入服务中,除非是能够处理异常并可从中恢复的 EJB。
总结为一下几点:
只有一个方法可以使用此注释进行注解;
被注解方法不得有任何参数;
被注解方法返回值为void;
被注解方法不得抛出已检查异常;
被注解方法需是非静态方法;
此方法只会被执行一次;

被注解的Servlet生命周期
需要注意的是,注解会多多少少地影响到服务器的启动速度。服务器在启动时候会遍历Web 应用的WEB-INF/classes下的所有class文件与WEB-INF/lib下的所有jar文件,以检查哪些类使用了注解。如果应用程序中没有 使用任何注解,可以在Web.xml中设置的metadata-complete属性为true.(支持@PostConstruct和 @PreDestroy的服务器需要支持Servlet2.5规范。Tomcat5.x仅支持Servlet2.4规范。)

我现在要说的是用实例说明它有什么作用。
比如说我有一种情况,在我的servlet初始化加载之前我想处理一些东西,像加载缓存等等。
怎么做。@PostConstruct就派上用场了。那为什么这玩意用的不多呢,这是因为如果初始化之前我们要加载或处理某些玩意完全可以在构造器初始化时就处理了,但这种方法需要自己重写构造器。好吧。直接上代码看看具体用它的时候怎么做的。


@PostConstruct注解
应用场景:当你需要往Bean里注入一个其父类中定义的属性,而你又无法复写父类的属性或属性的setter方法时

public class UserDaoImpl extends HibernateDaoSupport implements UserDao { 
private SessionFactory mySessionFacotry; 
@Resource 
public void setMySessionFacotry(SessionFactory sessionFacotry) { 
this.mySessionFacotry = sessionFacotry; 

@PostConstruct 
public void injectSessionFactory() { 
super.setSessionFactory(mySessionFacotry); 


这里通过@PostConstruct,为UserDaoImpl的父类里定义的一个sessionFactory私有属性,注入了我们自己定义的sessionFactory(父类的setSessionFactory方法为final,不可复写),之后我们就可以通过调用 super.getSessionFactory()来访问该属性了。

 

posted @ 2018-04-09 11:50  大-盖伦  阅读(338)  评论(0编辑  收藏  举报