spring成神之路-基礎(小白也能看懂)
阿新 • • 發佈:2019-01-13
基礎
1.什麼是IOC
控制反轉(Inversion of Control,縮寫為IoC),是面向物件程式設計中的一種設計原則,可以用來減低計算機程式碼之間的耦合 度。其中最常見的方式包含: 1)依賴注入(Dependency Injection,簡稱DI) 2)依賴查詢(Dependency Lookup,簡稱DL) 3)依賴拖拽(Dependency Pull,簡稱DP) 1 什麼是依賴注入? 應用元件不應該負責查詢資源或者其他依賴的協作物件。配置物件的工作應該由IoC容器負責,“查詢資源”的邏輯應該從 應用元件的程式碼中抽取出來,交給IoC容器負責,通俗的說,我們在程式碼中不需要再自己new一個物件,Sping會根據自 己的規則將合適的物件動態的分配給我們類中的屬性,這樣的好處是後期我們可能需要變動此類但不需要修改此處的代 碼,即降低了耦合也易於維護。 2 什麼是依賴查詢 DL是IOC的另外一種實現,在需要的時候通過呼叫框架提供的方法來獲取物件,獲取時需要提供相關的配置檔案路徑、 key等資訊;說白了就是根據條件需要自己手動查詢獲取需要的資訊,是需要使用者自己去控制的。 3 什麼是依賴拖拽 依賴拖拽與依賴查詢使用方式上差不多,區別就是依賴查詢是在業務元件程式碼中進行的,依賴拖拽是從一個集中的註冊 處,在特定的地點執行。
2.為什麼要使用Spring IOC?
1.在日常程式開發過程當中,我們推薦面向抽象程式設計,面向抽象程式設計會產生類的依賴,當然如果你夠強大可以自己寫一個管理的 容器也可以不使用,但是既然spring自己實現了而且還很強大,那我們有什麼理由不用呢。 2.當我們有了一個管理物件的容器之後,類的產生過程也交給了容器,而我們可以專心的關注自己的業務。 Spring IOC的實現思路和方法 spring實現IOC的思路是提供一些配置資訊用來描述類之間的依賴關係,然後由容器去解析這些配置資訊,繼而維護好物件之間 的依賴關係,前提是物件之間的依賴關係必須在類中定義好,比如A.class中有一個B.class的屬性,那麼我們可以理解為A依賴了B; spring實現IOC的思路大致可以拆分成3點 1.應用程式中提供類,提供依賴關係(屬性或者構造方法) 2.把需要交給容器管理的物件通過配置資訊告訴容器(xml、annotation,javaconfig) 3.把各個類之間的依賴關係通過配置資訊告訴容器 配置這些資訊的方法有三種分別是xml,annotation(需要依賴xml或javaconfig)和javaconfig(推薦使用,可以不用配 置xml檔案) 維護的過程稱為自動注入,自動注入的方法包括 '構造方法注入' 和'setter注入'(介面注入在Spring4就被拋棄了) 自動注入的值可以是物件,陣列,map,list和常量等
3.注入的兩種實現方式
setter注入 setter注入需要我們在被注入的類中實現對應屬性的set方法,值型別設定非常簡單,可以參考其它部落格或者該文件: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html 構造器注入 構造器注入需要我們在自己的類中實現構造方法,按照定義順序相應賦值,當然也可以通過c:名稱空間實現,可以參考文件: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html 屬性設定時的另類寫法: 可以通過c:或p:名稱空間進行值物件的賦值,但是需要在<beans>標籤中新增相應的說明和定義路徑,p-namespace不需要 在.xsd中定義,預設已在spring核心中定義,因此不需要再引入.xsd檔案。
4.怎麼獲取對應的物件
1.基於xml的,ClassPathXmlApplicationContext不會自動開啟註解的功能,因此需要自己在配置檔案中開啟註解:
ClassPathXmlApplicationContext classContext = new ClassPathXmlApplicationContext("存放xml檔案路徑");
IndexDaoService indexDaoService = (IndexDaoService)classContext.getBean("配置時的bean名稱");
2.基於javaconfig的,AnnotationConfigApplicationContext已經開啟瞭解析註解的功能,因此只需要配置掃描包路徑:
AnnotationConfigApplicationContext annotationContext = new AnnotationConfigApplicationContext(配置
的java類.class);
IndexDaoService indexDaoService = (IndexDaoService)annotationContext .getBean("配置時的bean名稱");
(IndexDaoService是自己定義的類,首行是獲取相應的IOC容器方法)
5.spring配置檔案
5.1 application.xml
1.在application.xml中可以開啟註解以及掃描,Spring3需要兩個設定項,在Spring4以及以後的版本中可以只通過
<context:component-scan base-package="掃描的包路徑"/>設定項開啟註解以及配置掃描路徑。
2.在<beans>新增default-autowire="注入型別"可以開啟spring的自動裝配(全域性),注入型別有byName、byType、no等,當開啟自動
裝配時我們不需要再通過配置檔案或者註解來維護類與類之間的依賴關係,spring會自動維護。當我們使用byType時只能有一個
實現類。在使用byName時需要在對應的類中提供setAbCd()方法,Spring會通過set方法的字尾名稱abCd來查詢對應的bean注入
到相關的bean(@resorce也是通過byName來查詢bean,但@resource是通過屬性名來查詢的,而且不需要提供set方法),no會
關閉自動 裝配,當然也可以配置單個bean的裝配方式(在bean中新增autowire=“”屬性)。
5.2 javaConfig配置檔案
@Configuration //表明這個類是一個Spring配置檔案
@ComponentScan("com.cxj") //開啟註解以及定義要掃描的包路徑
//當使用javaconfig編碼風格時,Spring不會再載入xml檔案,當我們需要混合使用時,需要新增該註解
@ImportResource("classpath:spring.xml")
public class Spring {
}
5.3 自定義bean名稱生成策略
1.繼承BeanNameGenerator,重寫方法
2.在xml中配置<context:component-scan base-package="org.example" name-generator="org.example.MyNameGenerator"
/>,或在javaconfig中新增@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
6 BEAN SCOP
1 singleton :表明此bean在spring整個生命週期只產生一個物件
2 prototype : 每次獲取bean時會新建一個物件
*3 當在singleton的bean中引入prototype的bean時,會產生一個問題,因為singleton的bean只會產生一次例項化,因此引入的
prototype的bean也只會初始化一次,導致失去了prototype的意義。
解決方法:
1.實現ApplicationContextAware介面,建立ApplicationContext屬性,然後通過該上下文getBean;
2.建立一個抽象方法,返回型別為需要的引入型別,然後在方法上添加註解@Lookup
java繼承後或實現後的子類在強轉成父類後,實際上只是限制了強轉後的例項的訪問方法許可權,對原類並沒有影響(自己的理解)