0%

java | 注解 @PostConstruct

该注解很有意思,在这里先说一下。


参考资料



介绍


@PostConstructjava5 的时候引入的注解,指的是在项目启动的时候执行这个方法,也可以理解在类加载的时候,为当前类初始化一些数据。

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

该注解修饰的是一个非静态的 void 方法。

通常作为前期启动的还有 CommandLineRunner ,但是,两者的作用不一样。

@PostConstruct 更针对性于当前类文件,而 CommandLineRunner 更服务于整个项目。

具体的可以查看。

在项目还没有启动成功的时候,@PostConstruct 已经执行完了,因为 @PostConstruct 是在 Init 类注入完成后立马执行的,它并不依赖于项目的启动。


启动顺序


单类的中的启动顺序

Constructor >> @Autowired/@Value >> @PostConstruct
  • Constructor
    • 构造方法

同一个类中多个@PostConstruct,无互相依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@PostConstruct
public void test01(){
System.out.println("test01");
}
@PostConstruct
public void test02(){
System.out.println("test02");
}
@PostConstruct
public void test03(){
System.out.println("test03");
}
@PostConstruct
public void test04(){
System.out.println("test04");
}
@PostConstruct
public void test05(){
System.out.println("test05");
}
@PostConstruct
public void test06(){
System.out.println("test06");
}
@PostConstruct
public void test07(){
System.out.println("test07");
}

顺序为随机。

嵌套的启动顺序

有时候 Class A@PostConstruct 注解的方法中的代码执行,需要等待 Class B@PostConstruct注解方法中的代码执行完后,拿到结果,才能执行,也就是中A中某些代码的执行需要依赖B中代码执后的结果。

此时就需要B先执行完,再执行A,可以在A中先注入B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Component
public class BeanA {

@Autowired
private BeanB beanB;

public BeanA() {
System.out.println("这是Bean A 的构造方法");
}


@PostConstruct
private void init() {
System.out.println("这是BeanA 的 init 方法");
beanB.testB();
}
}

@Component
public class BeanB {

@PostConstruct
private void init() {
System.out.println("这是BeanB 的 init 方法");
}

public BeanB() {
System.out.println("这是Bean B 的 构造方法");
}

void testB() {
System.out.println("这是Bean B 的 testB 方法");
}
}
这是Bean A 的构造方法
这是Bean B的 构造方法
这是BeanB 的 init 方法
这是BeanA 的 init 方法
这是Bean B 的 testB 方法

子父类

子类实例化过程中会调用父类中的 @PostConstruct 方法!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Component
public class TestRootClass {

public TestRootClass() {
System.out.println("Root Constructor");
}

@PostConstruct
public void sayHello() {
System.out.println("Hello! I am Root");
}

}
@Component
public class TestChildClass extends TestRootClass{

public TestChildClass() {
System.out.println("Child Constructor");
}

@PostConstruct
public void sayBye() {
System.out.println("Bye! I am Child");
}

}

打印结果

Root Constructor
Child Constructor
Hello! I am Root
Bye! I am Child
Root Constructor
Hello! I am Root
请我喝杯咖啡吧~