@PostConstruct注解
@PostConstruct注解好多人以为是Spring提供的。其实是Java自己的注解。
Java中该注解的说明:@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
实战:在静态方法中调用依赖注入的Bean中的方法。
如果想在生成对象时完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入,那么久无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
-
因为当调用构造函数时,bean还没有初始化-即没有注入依赖项。在
@PostConstruct
方法完全初始化bean,您可以使用依赖项。 -
因为这是保证在bean生命周期中只调用一次此方法的契约。一个bean可能会在其内部工作过程中被容器多次实例化(虽然不太可能),但它保证
@PostConstruct
只会被调用一次。
package com.example.studySpringBoot.util;
import com.example.studySpringBoot.service.MyMethorClassService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MyUtils {
private static MyUtils staticInstance = new MyUtils();
@Autowired
private MyMethorClassService myService;
@PostConstruct
public void init(){
staticInstance.myService = myService;
}
public static Integer invokeBean(){
return staticInstance.myService.add(10,20);
}
考虑以下情况:
public class Car {
@Inject
private Engine engine;
public Car() {
engine.initialize();
}
...}
由于CAR必须在字段注入之前实例化,因此在构造函数执行期间注入点引擎仍然为空,从而导致NullPointerException。
这个问题可以通过以下两种方法来解决Java的JSR-330依赖注入Java@PostConstruct方法注释的构造函数注入或JSR 250公共注释。
@PostConstruct
JSR-250定义了一组常见的注释,这些注释已经包含在JavaSE 6中。
PostConstruct注释用于在执行任何初始化时执行依赖注入后需要执行的方法。必须在类投入服务之前调用此方法。所有支持依赖注入的类都必须支持此注释。
JSR-250章。2.5 javax.notation.PostConstruct
@PostConstruct注释允许在实例化并执行所有注入之后执行方法的定义。
public class Car {
@Inject
private Engine engine;
@PostConstruct
public void postConstruct() {
engine.initialize();
}
...}
代码被移到带有@PostConstruct注释的方法中,而不是在构造函数中执行初始化。
后构造方法的处理是一个简单的问题,即查找所有带有@PostConstruct注释的方法,然后依次调用它们。
private void processPostConstruct(Class type, T targetInstance) {
Method[] declaredMethods = type.getDeclaredMethods();
Arrays.stream(declaredMethods)
.filter(method -> method.getAnnotation(PostConstruct.class) != null)
.forEach(postConstructMethod -> {
try {
postConstructMethod.setAccessible(true);
postConstructMethod.invoke(targetInstance, new Object[]{});
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
});}
后构造方法的处理必须在实例化和注入完成后执行。
转载:https://blog.csdn.net/qq360694660/article/details/82877222