在Spring Boot中,@PostConstruct 注解的作用

百度找了以下关于它的描述,有的说是在构造函数执行之后才会执行该注解标注的方法,有的则说需要 autowried 注入之后才会被执行。
 
因此用几个测试类测试以下它的不同情况下的执行情况。查看它的定义,它是java自带的注解:

package javax.annotation;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

/*
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:
*/

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

新建几个测试的组件:

  • TestCompoent1
  • TestCompoent2
  • TestCompoent3
  • TestCompoent4

3个Class都有默认的无参构造方法,和 @PostConstruct修饰的无参init() 方法
他们的区别是:
 
TestCompoent1 带有 @Component 注解,也就是说会在ApplicationContext 初始化完成之后,被注册到容器中。
 
TestCompoent2 没有 @Component 注解修饰。
 
TestComponent3 同样没有 @Component 注解修饰,但是它在TestComponent1中的 TestComponent3 component3() 方法里用 @Bean 注解。
 
TestComponent4 也没有 @Component 注解修饰,它被以代码的方式实例化。


TestCompoent1 :

@Component
public class TestComponent1 {
    public TestComponent1()
    {
        System.out.println("-----------------------------------------");
        System.out.println("TestComponent1 constructed");
        System.out.println("-----------------------------------------");
    }
    @PostConstruct
    public void init()
    {
        System.out.println("-----------------------------------------");
        System.out.println("TestComponent1 @PostConstruct annotated method executed");
        System.out.println("-----------------------------------------");
    }

    @Bean
    public  TestComponent3 component3()
    {
        return new TestComponent3();
    }
}

TestComponent2:

public class TestComponent2 {
    public TestComponent2()
    {
        System.out.println("-----------------------------------------");
        System.out.println("TestComponent2 constructed ");
        System.out.println("-----------------------------------------");
    }

    @PostConstruct
    public void init()
    {
        System.out.println("-----------------------------------------");
        System.out.println("TestComponent2 @PostConstruct init() executed ");
        System.out.println("-----------------------------------------");
    }
}

TestComponent3:

public class TestComponent3 {
    public TestComponent3() {
        System.out.println("-----------------------------------------");
        System.out.println("TestComponent3 constructed ");
        System.out.println("-----------------------------------------");
    }

    @PostConstruct
    public void init()
    {
        System.out.println("-----------------------------------------");
        System.out.println("TestComponent3  @PostConstruct annotated method executed");
        System.out.println("-----------------------------------------");
    }
}


TestComponent4:

public class TestComponent4 {
    public TestComponent4()
    {
        System.out.println("-----------------------------------------");
        System.out.println("TestCompoent4 default construct executed");
        System.out.println("-----------------------------------------");
    }
    @PostConstruct
    public void init()
    {
        System.out.println("-----------------------------------------");
        System.out.println("TestCompoent4 @PostConstruct annotated method executed");
        System.out.println("-----------------------------------------");
    }
}
        TestApplication.run(MsGatewayApplication.class, args);
        TestComponent4 testComponent4 =new TestComponent4();

接下来运行 SpringBoot 应用程序:

在Spring Boot中,@PostConstruct 注解的作用_第1张图片
在这里插入图片描述

可以看到 :

  • TestComponent1 和 TestComponent3 的构造函数和 @PostConstruct 修饰的 init() 方法都有有被执行。
  • TestComponent2 的则都没有执行。
  • TestComponent4 有执行构造函数,但是没有执行 init() 方法。

TestComponent2 和 TestComponent4 都没有被注册到容器管理中,@PostConstruct 执行的前提是class有被注册到Bean,它的执行顺序在构造函数之后


在Spring容器管理中,它的执行顺序:

ApplicationContextCreated
Bean Registrered
Construct
PostConstruct

查看它的描述,这个注解被用来注释某个方法,在依赖注入完成之后,完成一些初始化的操作,它有以下几个介绍:

  • 在class被载入服务前,这个方法会被调用
  • 在它定义在非拦截器类型 (non-interceptor) 的class中时,它不能有任何参数: void METHOD_NAME()
  • 在它定义在拦截器类型 (interceptor) 的class中时,它需要有一个 InvocationContext 类型的参数:void METHOD_NAME(InvocationContext)
  • 它的访问修饰符应该是 public, protected, package-private 或 private的
  • 当它在应用程序客户端中时,它不能是静态的(static)
  • 它或许应该是用 final 修饰的

如果不是在拦截器中使用这个注解,则不要有任何参数,因为应用程序只是通过 @PostConstruct 识别出这个要执行的方法,它并不能处理不同数量和不同类型的参数(会报错)。
 
但是在拦截器类型 (interceptor) 中定义的该方法似乎需要接收一个InvocationContext 类型的参数,这个我并没有测试过。

你可能感兴趣的:(spring,boot,java,springboot,spring)