1、IOC控制反轉概念
控制反轉(IOC)是一種經過描述(在Java中能夠是XML或者是註解)並經過第三方去生產或獲取特定對象的方式。
主動建立模式,責任在於開發者,而在被動模式下,責任歸於Ioc容器,基於這種被動形式,咱們就是對象被反轉了。
2、Spring IoC容器的初始化和依賴注入
Bean的定義何處是花再Spring Ioc容器中是兩大步驟,它是先定義,而後初始化和依賴注入。
Bean的定義分爲3步:
(1)Resource定位,這步是Spring IoC容器根據開發者的配置,進行資源定位,在Spring的開發中,經過xml和註解都是十分常見的方式,
定位的內容是由開發者所提供的。
(2)BeanDefinition的載入,這個時候只是將Resource定位到的信息,保存到Bean定義(BeanDefinition)中,此時不會建立Bean的實例。
(3)BeanDefinition的註冊,這個過程就是將BeanDefinition的信息發佈到Spring IoC容器中,注意此時仍沒有對應的Bean的實例被建立。
作完上述3個步驟,Bean就在Spring IoC容器中被定義,而沒有被初始化,更沒有完成依賴注入,也就是說沒有注入資源給Bean,那麼它還不能徹底使用。
對於初始化和依賴注入,SpringBean還有一個配置選項--lazy-init,其含義就是是否初始化Spring Bean。在沒有任何配置的狀況下,它的默認值未default,
實際值是false,也就是說Spring IoC容器會默認自動初始化Bean,若是將它的值設置爲true,那麼只有咱們使用Spring IoC容器的getBean方法獲取它時,它纔會
進行Bean的初始化,完成依賴注入。
3、Sprng Bean的生命週期:
Spring IoC容器的本質目的就是爲了管理Bean。對於Bean而言,在容器中存在其生命週期,它的初始化和銷燬也須要一個過程,在一些須要自定義的過程當中,咱們可
插入代碼取改變它們的一些行爲,以知足特定的需求,這就須要使用到Spring Bean的生命週期的知識了。
生命週期主要是爲了瞭解Spring IoC容器初始化和銷燬Bean的過程,經過對它的學習就能夠知道如何在初始化和銷燬的時候加入自定義的方法,以知足特定的需求。
如下是展現Spring IoC容器初始化和銷燬Bean的過程
Spring Bean生命週期的步驟:
(1)若是Bean實現了接口BeanNameAware的setBeanName方法,那麼它就會調用這個方法。
(2)若是Bean實現了接口BeanFactoryAware的setBeanFactory方法,那麼它就會調用這個方法。
(3)若是Bean實現了接口ApplicationContextAware接口的setApplicationContext方法,且Spring IoC容器也必須有一個ApplicationContext接口的實現子類,
那麼纔會調用這個方法,不然是不調用的。
(4)若是Bean實現了BeanPostProcessBeforeInitalization方法,那麼它會調用這個方法。
(5)若是Bean實現了接口BeanFactoryPostProcessor的afterPropertiesSet方法,那麼它就會調用這個方法。
(6)若是Bean自定義了初始化方法,它就會調用已定義的初始化方法。
(7)若是Bean實現接口BeanPostProcessor的postProcessAfterInitialization方法,完成了這些調用,這個時候Bean就完成了初始化,那麼Bean就生存在Spring IoC
的容器中了,使用者就能夠從中獲取Bean的服務。
當服務器正常關閉,或者遇到其餘關閉SpringIoC容器的事件,它就會調用對應的方法來完成Bean的銷燬,其步驟以下:
(1)若是Bean實現了接口DisposableBean的Destory方法,那麼就會調用它。
(2)若是定義了自定義銷燬方法,那麼就會調用它。
4、Spring Bean生命週期測試
建立一個POJO類:UserBean.javahtml
1 package com.xfwl.spring.beans; 2 /** 3 * Pojo實體類 4 * @author Jason 5 * 6 */ 7 public class UserBean { 8 private String uname; 9 private String upwd; 10 public UserBean(){} 11 public UserBean(String uname,String upwd){ 12 this.uname=uname; 13 this.upwd=upwd; 14 } 15 public String getUname() { 16 return uname; 17 } 18 public void setUname(String uname) { 19 this.uname = uname; 20 } 21 public String getUpwd() { 22 return upwd; 23 } 24 public void setUpwd(String upwd) { 25 this.upwd = upwd; 26 } 27 }
建立一個管理類:Manager.javajava
1 package com.xfwl.spring.beans; 2 3 import org.springframework.beans.BeansException; 4 import org.springframework.beans.factory.BeanFactory; 5 import org.springframework.beans.factory.BeanFactoryAware; 6 import org.springframework.beans.factory.BeanNameAware; 7 import org.springframework.beans.factory.DisposableBean; 8 import org.springframework.beans.factory.InitializingBean; 9 import org.springframework.context.ApplicationContext; 10 import org.springframework.context.ApplicationContextAware; 11 /** 12 * 13 * @function 14 * @author 小風微涼 15 * @time 2018-7-10 上午11:32:01 16 */ 17 public class Manager implements BeanNameAware, BeanFactoryAware,ApplicationContextAware, InitializingBean,DisposableBean{ 18 /**屬性和setter、getter方法**/ 19 private UserBean user=null; 20 21 public UserBean getUser() { 22 return user; 23 } 24 public void setUser(UserBean user) { 25 this.user = user; 26 } 27 28 /**Bean生命週期測試**/ 29 public void init(){ 30 System.out.println("【"+this.getClass().getSimpleName()+"】執行自定義初始化方法!"); 31 } 32 public void mydestory(){ 33 System.out.println("【"+this.getClass().getSimpleName()+"】執行自定義銷燬法!"); 34 } 35 public void login(){ 36 System.out.println("【登陸操做】,登陸信息:uname:"+this.user.getUname()+",upwd="+this.user.getUpwd()); 37 } 38 @Override 39 public void afterPropertiesSet() throws Exception { 40 System.out.println("【"+this.getClass().getSimpleName()+"】調用了InitializingBean接口的afterPropertiesSet方法!"); 41 } 42 43 @Override 44 public void setApplicationContext(ApplicationContext arg0)throws BeansException { 45 System.out.println("【"+this.getClass().getSimpleName()+"】調用了ApplicationContextAware接口的setApplicationContext方法!"); 46 } 47 48 @Override 49 public void setBeanFactory(BeanFactory arg0) throws BeansException { 50 System.out.println("【"+this.getClass().getSimpleName()+"】調用了BeanFactoryAware接口的setBeanFactory方法!"); 51 } 52 53 @Override 54 public void setBeanName(String arg0) { 55 System.out.println("【"+this.getClass().getSimpleName()+"】調用了BeanNameAware接口的setBeanName方法!"); 56 } 57 @Override 58 public void destroy() throws Exception { 59 System.out.println("調用接口DisposableBean的destory方法!"); 60 } 61 }
配置:applicationContext.xmlspring
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> 7 <!-- <bean id="user_Tom" class="com.xfwl.spring.beans.UserBean"> 8 <property name="uname" value="tom"></property> 9 <property name="upwd" value="123"></property> 10 </bean> 11 <bean id="user_Jack" class="com.xfwl.spring.beans.UserBean"> 12 <property name="uname" value="jack"></property> 13 <property name="upwd" value="123"></property> 14 </bean> --> 15 <bean id="user_xfwl" class="com.xfwl.spring.beans.UserBean"> 16 <property name="uname" value="小風微涼"></property> 17 <property name="upwd" value="123456"></property> 18 </bean> 19 <bean id="BeanPostProcessorImpl" class="com.xfwl.spring.beans.BeanPostProcessorImpl"/> 20 <bean id="manager" class="com.xfwl.spring.beans.Manager" 21 init-method="init" destroy-method="mydestory" lazy-init="default"> 22 <property name="user" ref="user_xfwl"></property> 23 </bean> 24 </beans>
建立一個測試類:TestBean.javaexpress
1 package com.xfwl.spring.beans; 2 import org.springframework.context.ApplicationContext; 3 import org.springframework.context.support.ClassPathXmlApplicationContext; 4 import org.springframework.context.support.FileSystemXmlApplicationContext; 5 6 /** 7 * Spring Ioc測試 8 * @function 9 * @author 小風微涼 10 * @time 2018-7-10 上午9:55:15 11 */ 12 public class TestBean { 13 //絕對路徑 14 private static final String xmlAbsPath="E:\\JAVA學習[【進階學習】\\JAVA回爐深造\\進階測試工做空間\\多線程\\SpringSources\\src\\applicationContext.xml"; 15 //項目相對路徑 16 private static final String xmlRelPath="applicationContext.xml"; 17 public static void main(String[] args) { 18 /*//第一種解析方式 19 FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(xmlAbsPath); 20 UserBean tom =(UserBean) ctx.getBean("user_Tom"); 21 System.out.println(tom.getUname()); 22 23 //第二種解析方式 24 ApplicationContext context=new ClassPathXmlApplicationContext(xmlRelPath); 25 UserBean jack =(UserBean) context.getBean("user_Jack"); 26 System.out.println(jack.getUname());*/ 27 28 //測試Bean的生命週期 29 FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(xmlAbsPath); 30 Manager manager =(Manager) ctx.getBean("manager"); 31 manager.login(); 32 ctx.close(); 33 } 34 }
運行結果:apache
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. 【UserBean】對象:user_xfwl開始實例化 【UserBean】對象:user_xfwl完成實例化 【Manager】調用了BeanNameAware接口的setBeanName方法! 【Manager】調用了BeanFactoryAware接口的setBeanFactory方法! 【Manager】調用了ApplicationContextAware接口的setApplicationContext方法! 【Manager】對象:manager開始實例化 【Manager】調用了InitializingBean接口的afterPropertiesSet方法! 【Manager】執行自定義初始化方法! 【Manager】對象:manager完成實例化 【登陸操做】,登陸信息:uname:小風微涼,upwd=123456 調用接口DisposableBean的destory方法! 【Manager】執行自定義銷燬法!
能夠看到,在applicationContext.xml中配置一個Bean,而後getBean(),整個Bean的生命週期。服務器
5、上文中Spring的Jar配置說明多線程
1 1.Spring依賴包配置:(核心功能:IOC容器) 2 *spring的核心jar包:spring.jar 3 *spring-context.jar包:獲取xml配置bean對象的相關類支持,好比ApplicationContext.java 4 *spring-beans.jar包:獲取xml配置bean對象的相關類支持,好比BeanFactory.java 5 *spring-expression.jar:提供類的支持,好比:FileSystemXmlApplicationContext.java,用於解析xml配置信息 6 *記錄日誌jar包:log4j.jar 7 *apache的記錄日誌jar包:commons-logging.jar(日誌的抽象) 8 9 特別說明: 10 若是項目的.classpath中有log4j.jar,那麼會優先用log4j.jar, 11 若是沒有log4j.jar,則會會調用sun的JDK中的記錄日誌的工具包, 12 若是都沒有,最後使用:commons-logging.jar 會調用自己的日誌記錄功能來記錄日誌 13 14 commons-logging.jar是日誌功能的抽象, 15 優先級別以下: 16 log4j.jar-->jdk自己的日誌功能-->commons-logging.jar自己的日誌記錄功能