天天看點

當spring 容器初始化完成後執行某個方法

在做web項目開發中,尤其是企業級應用開發的時候,往往會在工程啟動的時候做許多的前置檢查。

比如檢查是否使用了我們組禁止使用的mysql的group_concat函數,如果使用了項目就不能啟動,并指出哪個檔案的xml檔案使用了這個函數。

而在spring的web項目中,我們可以介入spring的啟動過程。我們希望在spring容器将所有的bean都初始化完成之後,做一些操作,這個時候我們就可以實作一個接口:

1

2

3

4

5

6

7

<code>package</code> <code>com.yk.test.executor.processor</code>

<code>public</code> <code>class</code> <code>instantiationtracingbeanpostprocessor </code><code>implements</code> <code>applicationlistener&lt;contextrefreshedevent&gt; {</code>

<code>@override</code>

<code>public</code> <code>void</code> <code>onapplicationevent(contextrefreshedevent event) {</code>

<code>//需要執行的邏輯代碼,當spring容器初始化完成後就會執行該方法。</code>

<code>}</code>

  

同時在spring的配置檔案中,添加注入:

<code>&lt;!-- 當spring容器啟動完成後執行下面的這個bean --&gt;</code>

<code>&lt;bean </code><code>class</code><code>=</code><code>"com.yk.test.executor.processor.instantiationtracingbeanpostprocessor"</code><code>/&gt;</code>

但是這個時候,會存在一個問題,在web 項目中(spring mvc),系統會存在兩個容器,一個是root application context ,另一個就是我們自己的 projectname-servlet context(作為root application context的子容器)。

這種情況下,就會造成onapplicationevent方法被執行兩次。為了避免上面提到的問題,我們可以隻在root application context初始化完成後調用邏輯代碼,其他的容器的初始化完成,則不做任何處理,修改後代碼

如下:

<code>if</code><code>(event.getapplicationcontext().getparent() == </code><code>null</code><code>){</code><code>//root application context 沒有parent,他就是老大.</code>

其實更簡單的方法是使用注解:`@postconstruct`,隻需要在需要啟動的時候執行的方法上标注這個注解就搞定了。

注解描述如下:

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

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

<code>/*</code>

<code> </code><code>* copyright (c) 2005, 2013, oracle and/or its affiliates. all rights reserved.</code>

<code> </code><code>* oracle proprietary/confidential. use is subject to license terms.</code>

<code> </code><code>*</code>

<code> </code><code>*/</code>

<code>package</code> <code>javax.annotation;</code>

<code>import</code> <code>java.lang.annotation.*;</code>

<code>import</code> <code>static</code> <code>java.lang.annotation.elementtype.*;</code>

<code>import</code> <code>static</code> <code>java.lang.annotation.retentionpolicy.*;</code>

<code>/**</code>

<code> </code><code>* the postconstruct annotation is used on a method that needs to be executed</code>

<code> </code><code>* after dependency injection is done to perform any initialization. this</code>

<code> </code><code>* method must be invoked before the class is put into service. this</code>

<code> </code><code>* annotation must be supported on all classes that support dependency</code>

<code> </code><code>* injection. the method annotated with postconstruct must be invoked even</code>

<code> </code><code>* if the class does not request any resources to be injected. only one</code>

<code> </code><code>* method can be annotated with this annotation. the method on which the</code>

<code> </code><code>* postconstruct annotation is applied must fulfill all of the following</code>

<code> </code><code>* criteria:</code>

<code> </code><code>* &lt;p&gt;</code>

<code> </code><code>* &lt;ul&gt;</code>

<code> </code><code>* &lt;li&gt;the method must not have any parameters except in the case of</code>

<code> </code><code>* interceptors in which case it takes an invocationcontext object as</code>

<code> </code><code>* defined by the interceptors specification.&lt;/li&gt;</code>

<code> </code><code>* &lt;li&gt;the method defined on an interceptor class must have one of the</code>

<code> </code><code>* following signatures:</code>

<code> </code><code>* void &lt;method&gt;(invocationcontext)</code>

<code> </code><code>* object &lt;method&gt;(invocationcontext) throws exception</code>

<code> </code><code>* &lt;i&gt;note: a postconstruct interceptor method must not throw application</code>

<code> </code><code>* exceptions, but it may be declared to throw checked exceptions including</code>

<code> </code><code>* the java.lang.exception if the same interceptor method interposes on</code>

<code> </code><code>* business or timeout methods in addition to lifecycle events. if a</code>

<code> </code><code>* postconstruct interceptor method returns a value, it is ignored by</code>

<code> </code><code>* the container.&lt;/i&gt;</code>

<code> </code><code>* &lt;/li&gt;</code>

<code> </code><code>* &lt;li&gt;the method defined on a non-interceptor class must have the</code>

<code> </code><code>* following signature:</code>

<code> </code><code>* void &lt;method&gt;()</code>

<code> </code><code>* &lt;li&gt;the method on which postconstruct is applied may be public, protected,</code>

<code> </code><code>* package private or private.&lt;/li&gt;</code>

<code> </code><code>* &lt;li&gt;the method must not be static except for the application client.&lt;/li&gt;</code>

<code> </code><code>* &lt;li&gt;the method may be final.&lt;/li&gt;</code>

<code> </code><code>* &lt;li&gt;if the method throws an unchecked exception the class must not be put into</code>

<code> </code><code>* service except in the case of ejbs where the ejb can handle exceptions and</code>

<code> </code><code>* even recover from them.&lt;/li&gt;&lt;/ul&gt;</code>

<code> </code><code>* @since common annotations 1.0</code>

<code> </code><code>* @see javax.annotation.predestroy</code>

<code> </code><code>* @see javax.annotation.resource</code>

<code>@documented</code>

<code>@retention</code> <code>(runtime)</code>

<code>@target</code><code>(method)</code>

<code>public</code> <code>@interface</code> <code>postconstruct {</code>