@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

posted @ 2020-09-30 11:53  彬在俊  阅读(9361)  评论(0编辑  收藏  举报