@PostConstruct 注解使用

2023-09-13 08:51:44
/**
 * 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:
 * <p>
 * <ul>
 * <li>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.</li>
 * <li>The method defined on an interceptor class MUST HAVE one of the
 * following signatures:
 * <p>
 * void &#060;METHOD&#062;(InvocationContext)
 * <p>
 * Object &#060;METHOD&#062;(InvocationContext) throws Exception
 * <p>
 * <i>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.</i>
 * </li>
 * <li>The method defined on a non-interceptor class MUST HAVE the
 * following signature:
 * <p>
 * void &#060;METHOD&#062;()
 * </li>
 * <li>The method on which PostConstruct is applied MAY be public, protected,
 * package private or private.</li>
 * <li>The method MUST NOT be static except for the application client.</li>
 * <li>The method MAY be final.</li>
 * <li>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.</li></ul>
 * @since Common Annotations 1.0
 * @see javax.annotation.PreDestroy
 * @see javax.annotation.Resource
 */

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}

注解的注释中描述:

这是一个需要执行的方法

在依赖注入已经做完。然后来执行实现。这个方法必须被调用在所有的类加载之前。

 The method annotated with PostConstruct MUST be invoked even
 * if the class does not request any resources to be injected

这个方法必须被调用(即使不需要任何类的资源注入的情况下)

方法可以被这个注解注释必须满足需求是:

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.

这个方法不能有任何的参数除非( interceptors in which case it takes an InvocationContext object as
 * defined by the Interceptors specification 除非由拦截器规范定义)

如果定义在拦截器中的话,必须有的特征

 * void &#060;METHOD&#062;(InvocationContext)
 * Object &#060;METHOD&#062;(InvocationContext) throws Exception

而且构造的拦截器方法不能抛出来应用异常,但是可以声明抛出检查异常(java.lang.Exception)。

抛出检查异常的条件:(

如果同一拦截器方法插入生命周期事件之外的业务或超时方法。如果一个PostConstruct  拦截器方法返回了一个值,那么将被容器忽略

如果在非拦截器上定义的方法必须具有下面的特征:

 void &#060;METHOD&#062;()

构造的方法可以使:public, protected, package private or private(引申一个问题:package private or private的区别? 见:https://blog.csdn.net/pmdream/article/details/84942066

The method MUST NOT be static except for the application client

这个方法不能是static的(except for the application client)

这个方法可以用final修饰

源码的注释已经照着翻译看完了

==============================================================================================

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

@PostConstruct

Public void someMethod() {}

public @PostConstruct void someMethod(){}

 被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行

也就是加载顺序

 服务器加载Servlet -> servlet 构造函数的加载 -> postConstruct ->init(init是在service 中的初始化方法. 创建service 时发生的事件.) ->Service->destory->predestory->服务器卸载serlvet

那么问题:spring中Constructor、@Autowired、@PostConstruct的顺序

Constructor >> @Autowired >> @PostConstruct

依赖注入的字面意思就可以知道,要将对象p注入到对象a,那么首先就必须得生成对象p与对象a,才能执行注入。所以,如果一个类A中有个成员变量p被@Autowired注解,那么@Autowired注入是发生在A的构造方法执行完之后的。

@PostConstruct应用场景:

如果想在生成对象时候完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入,那么就无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖注入完成后被自动调用。

(暂时写这么多,以后有新的感悟再填坑)

  • 作者:pmdream
  • 原文链接:https://blog.csdn.net/pmdream/article/details/84937023
    更新时间:2023-09-13 08:51:44