從jdk源碼上看,beanfactory實現類需要支持bean的完整生命周期,完整的初始化方法及其標準順序(格式:接口 方法)為:
1.beannameaware setbeanname 設置bean名稱
2.beanclassloaderaware setbeanclassloader 設置bean類加載器
3.beanfactoryaware setbeanfactory 設置bean工廠
4.environmentaware setenvironment 設置環境:profiles+properties
5.embeddedvalueresolveraware setembeddedvalueresolver 設置嵌入式值解析器
6.resourceloaderaware setresourceloader 設置資源載入器,只適用于在應用程序上下文中運行
7.applicationeventpublisheraware setapplicationeventpublisher注入應用事件發布器applicationeventpublisher
8.messagesourceaware setmessagesource 設置國際化支持
9.applicationcontextaware setapplicationcontext 設置應用上下文
10.servletcontextaware setservletcontext 設置servlet上下文
11.beanpostprocessors postprocessbeforeinitialization 執行bean處理器前置方法
12.initializingbean afterpropertiesset 執行初始化bean設置完屬性后置方法
13.a custom init-method definition 執行自定義初始化方法
14.beanpostprocessors postprocessafterinitialization 執行bean處理器后置方法
銷毀順序:
1.destructionawarebeanpostprocessors postprocessbeforedestruction 銷毀處理器的前置方法
2.disposablebean destroy bean銷毀回調方法
3.a custom destroy-method definition 用戶自定義銷毀方法
核心方法流程圖:
二、測試驗證
2.1分析原理
前面說的17個步驟都可以測試,我們選取其中的8個步驟進行測試如下:
初始化流程:
1.beannameaware setbeanname 設置bean名稱
3.beanfactoryaware setbeanfactory 設置bean工廠
11.beanpostprocessors postprocessbeforeinitialization 執行bean處理器前置方法
12.initializingbean afterpropertiesset 執行初始化bean設置完屬性后置方法
13.a custom init-method definition 執行自定義初始化方法
14.beanpostprocessors postprocessafterinitialization 執行bean處理器后置方法
銷毀流程:
2.disposablebean destroy bean銷毀回調方法
3.a custom destroy-method definition 用戶自定義銷毀方法
2.2 代碼清單
1.構建一個person類,實現beanfactoryaware, beannameaware, initializingbean, disposablebean接口。
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
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
|
package spring.ioc; import org.springframework.beans.beansexception; import org.springframework.beans.factory.beanfactory; import org.springframework.beans.factory.beanfactoryaware; import org.springframework.beans.factory.beannameaware; import org.springframework.beans.factory.disposablebean; import org.springframework.beans.factory.initializingbean; public class person implements beanfactoryaware, beannameaware, initializingbean, disposablebean { private string name; private string mobile; public person() { super (); system.out.println( "[構造器] 調用person的構造器實例化" ); } public string getname() { return name; } public void setname(string name) { system.out.println( "[屬性注入] name=" +name); this .name = name; } public string getmobile() { return mobile; } public void setmobile(string mobile) { system.out.println( "[屬性注入] mobile=" +mobile); this .mobile = mobile; } @override public void destroy() throws exception { system.out.println( "[接口disposablebean.destroy() ]" ); } @override public void afterpropertiesset() throws exception { system.out.println( "[接口initializingbean.afterpropertiesset() ]" ); } @override public void setbeanname(string name) { system.out.println( "[接口beannameaware.setbeanname() ]" ); } @override public void setbeanfactory(beanfactory beanfactory) throws beansexception { system.out.println( "[接口beanfactoryaware.setbeanfactory() ]" ); } public void myinit(){ system.out.println( "[init-method]調用<bean>的init-method屬性指定的初始化方法" ); } public void mydestory() { system.out.println( "[destroy-method]調用<bean>的destroy-method屬性指定的銷毀方法" ); } } |
2.自定義工廠后處理器,復寫postprocessbeanfactory方法,獲取bean定義后添加屬性mobile=110
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
|
package spring.ioc; import org.springframework.beans.beansexception; import org.springframework.beans.factory.config.beandefinition; import org.springframework.beans.factory.config.beanfactorypostprocessor; import org.springframework.beans.factory.config.configurablelistablebeanfactory; /** * * @classname:mybeanfactorypostprocessor * @description:自定義工廠后處理器 * @author diandian.zhang * @date 2017年10月25日下午7:14:09 */ public class mybeanfactorypostprocessor implements beanfactorypostprocessor { public mybeanfactorypostprocessor() { super (); system.out.println( "[mybeanfactorypostprocessor工廠后處理器]beanfactorypostprocessor實現類構造器??!" ); } @override public void postprocessbeanfactory(configurablelistablebeanfactory arg0) throws beansexception { system.out.println( "[mybeanfactorypostprocessor工廠后處理器]beanfactorypostprocessor.postprocessbeanfactory()獲取bean定義后添加屬性mobile=110" ); beandefinition bd = arg0.getbeandefinition( "person" ); bd.getpropertyvalues().addpropertyvalue( "mobile" , "110" ); } } |
3.自定義bean后處理器,復寫postprocessbeforeinitialization和postprocessafterinitialization2個方法,分別對應初始化前后時的操作。
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package spring.ioc; import org.springframework.beans.beansexception; import org.springframework.beans.factory.config.beanpostprocessor; /** * * @classname:mybeanpostprocessor * @description:自定義bean后處理器 * @author diandian.zhang * @date 2017年10月25日下午7:03:53 */ public class mybeanpostprocessor implements beanpostprocessor { public mybeanpostprocessor() { super (); system.out.println( "這是beanpostprocessor實現類構造器!!" ); } /** * * @description 初始化前,處理器 * @param bean * @param beanname * @return * @throws beansexception * @author diandian.zhang * @date 2017年10月25日下午7:07:02 * @see org.springframework.beans.factory.config.beanpostprocessor#postprocessbeforeinitialization(java.lang.object, java.lang.string) */ @override public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception { system.out.println( "beanpostprocessor接口方法postprocessbeforeinitialization對屬性進行更改!beanname=" +beanname); return bean; } /** * * @description 初始化后,處理器 * @param bean * @param beanname * @return * @throws beansexception * @author diandian.zhang * @date 2017年10月25日下午7:07:07 * @see org.springframework.beans.factory.config.beanpostprocessor#postprocessafterinitialization(java.lang.object, java.lang.string) */ @override public object postprocessafterinitialization(object bean, string beanname) throws beansexception { system.out.println( "beanpostprocessor接口方法postprocessafterinitialization對屬性進行更改!beanname=" +beanname); return bean; //注意,如果返回null,后續beanpostprocessor不會再執行 } } |
4.自定義實例化bean后處理器適配器,復寫postprocessbeforeinstantiation、postprocessbeforeinstantiation、postprocesspropertyvalues分別對應實例化bean前調用、實例化bean后調用、設置某個屬性時調用
注意:instantiationawarebeanpostprocessoradapter ,這里是實例化instantiation,不是初始化initialization?。?!
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
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package spring.ioc; import java.beans.propertydescriptor; import org.springframework.beans.beansexception; import org.springframework.beans.propertyvalues; import org.springframework.beans.factory.config.instantiationawarebeanpostprocessoradapter; /** * * @classname:myinstantiationawarebeanpostprocessor * @description:beanpostprocessor的子類,增加了更多自定方法 * @author diandian.zhang * @date 2017年10月25日下午7:09:15 */ public class myinstantiationawarebeanpostprocessor extends instantiationawarebeanpostprocessoradapter { public myinstantiationawarebeanpostprocessor() { super (); system.out.println( "這是instantiationawarebeanpostprocessoradapter實現類構造器!!" ); } // 接口方法、實例化bean之前調用 @override public object postprocessbeforeinstantiation( class <?> beanclass,string beanname) throws beansexception { system.out.println( "instantiationawarebeanpostprocessor調用postprocessbeforeinstantiation方法[實例化bean之前調用 ]beanname=" +beanname); return null ; } // 接口方法、實例化bean之后調用 @override public object postprocessafterinitialization(object bean, string beanname) throws beansexception { system.out .println( "instantiationawarebeanpostprocessor調用postprocessafterinitialization方法[實例化bean之后調用]beanname=" +beanname); return bean; } // 接口方法、設置某個屬性時調用 @override public propertyvalues postprocesspropertyvalues(propertyvalues pvs, propertydescriptor[] pds, object bean, string beanname) throws beansexception { system.out.println( "instantiationawarebeanpostprocessor調用postprocesspropertyvalues方法 pvs=" +pvs+ ",beanname=" +beanname); return pvs; } } |
5.測試類,使用classpathxmlapplicationcontext從xml中讀取bean配置文件生成applicationcontext容器應用上下文,這一步對應容器初始化。第二部從應用上下文中獲取bean。最后一步注冊一個關閉鉤子,在容器關閉時觸發。
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
|
package spring.ioc; import org.junit.test; 6 import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; 10 import spring.aop.xml.dao.dao; /** * * @classname:ioctest * @description:測試類 * @author diandian.zhang * @date 2017年10月25日下午4:42:01 */ public class ioctest { @test public void iocpersontest(){ system.out.println( "=============容器初始化======start=========" ); @suppresswarnings ( "resource" ) applicationcontext applicationcontext = new classpathxmlapplicationcontext( "simple_spring_bean.xml" ); //源碼入口 system.out.println( "=============容器初始化=======end========" ); system.out.println( "=============獲取person bean====start=======" ); person person = applicationcontext.getbean( "person" ,person. class ); //獲取bean system.out.println( "=============獲取person bean====end=======,person類名=" +person.getclass().getname()); system.out.println( "=============注冊關閉鉤子,關閉容器(jvm shutdown)時觸發鉤子!================" ); ((classpathxmlapplicationcontext)applicationcontext).registershutdownhook(); } } |
直接運行,結果如下:
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
|
=============容器初始化======start========= log4j:warn no appenders could be found for logger (org.springframework.core.env.standardenvironment). log4j:warn please initialize the log4j system properly. [mybeanfactorypostprocessor工廠后處理器]beanfactorypostprocessor實現類構造器!! [mybeanfactorypostprocessor工廠后處理器]beanfactorypostprocessor.postprocessbeanfactory()獲取bean定義后添加屬性mobile= 110 這是beanpostprocessor實現類構造器!! 這是instantiationawarebeanpostprocessoradapter實現類構造器??! instantiationawarebeanpostprocessor調用postprocessbeforeinstantiation方法[實例化bean之前調用 ]beanname=person [構造器] 調用person的構造器實例化 instantiationawarebeanpostprocessor調用postprocesspropertyvalues方法 pvs=propertyvalues: length= 2 ; bean property 'mobile' ; bean property 'name' ,beanname=person [屬性注入] mobile= 110 [屬性注入] name=張三 [接口beannameaware.setbeanname() ] [接口beanfactoryaware.setbeanfactory() ] beanpostprocessor接口方法postprocessbeforeinitialization對屬性進行更改!beanname=person [接口initializingbean.afterpropertiesset() ] [init-method]調用<bean>的init-method屬性指定的初始化方法 beanpostprocessor接口方法postprocessafterinitialization對屬性進行更改!beanname=person instantiationawarebeanpostprocessor調用postprocessafterinitialization方法[實例化bean之后調用]beanname=person =============容器初始化=======end======== =============獲取person bean====start======= =============獲取person bean====end=======,person類名=spring.ioc.person =============注冊關閉鉤子,關閉容器(jvm shutdown)時觸發鉤子!================ [接口disposablebean.destroy() ] [destroy-method]調用<bean>的destroy-method屬性指定的銷毀方法 |
總結流程:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/dennyzhangdd/p/7732273.html?utm_source=tuicool&utm_medium=referral