在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 应用程序:

在这里插入图片描述
在这里插入图片描述

可以看到 :

  • 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 类型的参数,这个我并没有测试过。

  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@PostConstruct注解作用是在对象创建完成之后自动调用标记的方法,可以在这个方法进行一些初始化操作。与构造函数不同,@PostConstruct注解的方法可以使用依赖注入的属性,因此可以在这个方法对依赖的属性进行一些操作,而不需要在构造函数手动传入。 使用@PostConstruct注解的方法需要满足以下条件: - 不能有参数 - 不能有返回值 - 不能抛出异常 - 可以是任意访问修饰符的非静态方法 如果一个类有多个使用@PostConstruct注解的方法,这些方法的执行顺序是不确定的。 在Spring Boot,@PostConstruct注解作用与上述相同,用于在Spring容器管理执行一些初始化操作。它的执行顺序是在ApplicationContextCreated、Bean Registrered、Construct之后,最后执行PostConstruct。 范例:<<引用:@PostConstruct注解作用和使用。 @PostConstruct注解javax.annotation包下的一个注解,它用于标记一个方法,在对象创建完成,依赖注入完成之后执行。 作用: @PostConstruct注解的方法会在对象创建完成之后自动调用,可以在这个方法进行一些初始化操作。与构造函数不同,@PostConstruct注解的方法可以使用依赖注入的属性,因此可以在这个方法对依赖的属性进行一些操作,而不需要在构造函数手动传入。 使用: 在需要使用@PostConstruct注解的方法上添加@PostConstruct注解。该方法不能有参数,不能有返回值,也不能抛出异常。@PostConstruct注解的方法可以是任意访问修饰符,可以是非静态方法。如果一个类有多个使用@PostConstruct注解的方法,这些方法的执行顺序是不确定的。 。引用:在Spring Boot,@PostConstruct 注解作用。在Spring容器管理,它的执行顺序: ApplicationContextCreated Bean Registrered Construct PostConstruct。>> @PostConstruct注解作用是在对象创建完成之后自动调用标记的方法,可以在这个方法进行一些初始化操作。与构造函数不同,@PostConstruct注解的方法可以使用依赖注入的属性,因此可以在这个方法对依赖的属性进行一些操作,而不需要在构造函数手动传入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值