1. 程式人生 > >SpringIOC的概念理解、構造器註入、setter註入、p命名空間註入、IOC容器介紹與比較

SpringIOC的概念理解、構造器註入、setter註入、p命名空間註入、IOC容器介紹與比較

get 集合 目的 schema 根據 字段名 操作 ioc容器 參考

1、IOC概念理解

  IOC(Inversion of Control)即“控制反轉”,不是什麽技術,而是一種設計思想。在Java開發中,Ioc意味著將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制,IOC容器負責實例化、定位、配置應用程序中的對象及建立這些對象間的依賴,由spring來負責控制對象的生命周期和對象間的關系。

  DI(Dependency Injection)即“依賴註入”:由容器動態的將某個依賴關系註入到組件之中。依賴註入的目的並非為軟件系統帶來更多功能,而是為了提升組件重用的頻率,並為系統搭建一個靈活、可擴展的平臺。

  例如:你將需要尋找的理想中的對象(胸大、屁股大、年輕、有文化)交給婚姻中介來控制,而不是你主動去找去控制尋找,由中介為你尋找(過程你毫不知情),你選擇是否接受中介為你匹配到的對象。這個過程中主動找理想對象的控制權從你到中介為:控制反轉;中介輸出給你的對象為:依賴註入;

(2)spring的兩種Ioc容器

BeanFactory:

  BeanFactory是基礎類型IOC容器。顧名思義,就是生產Bean的工廠。能夠提供完整的IOC服務。沒有特殊指定的話,其默認采用延遲初始化策略。只有當客戶端對象需要訪問容器中的某個受管對象的時候,才對該對象進行初始化和依賴註入操作。因此,相對來說,容器啟動初期的時候速度是比較快的。所需要的資源有限。所以,對資源有限,並且功能要求不是很嚴格的場景,BeanFactory是比較合適的IOC容器。

ApplicationContext:

  ApplicationContext是在BeanFactory的基礎上邊構建的,是相對比較高級的容器的實現,除了擁有BeanFactory的所有支持,ApplicationContext還提供了其他的高級特性。例如事件發布、國際化信息支持等。ApplicationContext所管理的對象,在該類型容器啟動之後,默認全部初始化並綁定完成。相對於BeanFactory來說,ApplicationContext會要求更多的系統資源。因為在啟動時就完成了所有的初始化,容器啟動的時間與BeanFactory相比會長一些。因此,ApplicationContext更適用於系統資源充足,並且要求更多功能的場景中。
   ApplicationContext間接繼承自BeanFactory,所以說它是構建與BeanFactory之上的IOC容器。 比較:   BeanFacotry是spring中比較原始的Factory。它無法支持spring的許多插件,如AOP功能、Web應用等。   ApplicationContext接口,它由BeanFactory接口派生而來,因而提供BeanFactory所有的功能。   ApplicationContext以一種更向面向框架的方式工作以及對上下文進行分層和實現繼承,   ApplicationContext包還提供了以下的功能: • MessageSource, 提供國際化的消息訪問
      • 資源訪問,如URL和文件 
      • 事件傳播 
      • 載入多個(有繼承關系)上下文 ,使得每一個上下文都專註於一個特定的層次,比如應用的 web層  
BeanFactroy采用的是延遲加載形式來註入Bean的,即只有在使用到某個Bean時(調用getBean()),才對該Bean進行加載實例化,這樣,我們就不能發現一些存在的Spring的配置問題。
而ApplicationContext則相反,它是在容器啟動時,一次性創建了所有的Bean。在容器啟動時,我們就可以發現Spring中存在的配置錯誤。

(3)Spring IOC 註入方式

3.1 setter註入:

技術分享圖片
1 <bean id="helloSpring" class="com.one.ssm.impl.HelloSpring">
2         <!--此處的value的註入是通過set方法-->
3         <property name="who" value="spring"></property>
4         <property name="you" value="123456789"></property>
5     </bean>
xml書寫

代碼書寫:

技術分享圖片
 1 public class HelloSpring {
 2     //定義who屬性,值通過spring框架進行設置
 3     private String who;
 4     private String you;
 5     public void setYou(String you) {
 6         this.you = you;
 7     }
 8     public void print(){
 9         System.out.println("Hello:"+this.getWho()+"!"+you);
10     }
11     public String getWho() {
12         return who;
13     }
14     public void setWho(String who) {
15         this.who = who;
16     }
17 }
18 測試類:
19 @Test
20     public void print() throws Exception {
21         ApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring/spring-impl.xml");
22         HelloSpring helloSpring= (HelloSpring) context.getBean("helloSpring");
23         helloSpring.print();
24     }
25 結果:Hello:spring!123456789
代碼

3.2 構造器註入

技術分享圖片
1   <!--構造註入實例-->
2     <bean id="math" class="com.one.ssm.impl.structorInjectionTest.MathDemo"></bean>
3     <bean id="english" class="com.one.ssm.impl.structorInjectionTest.EnglishDemo"></bean>
4     <bean id="StudyDemo" class="com.one.ssm.impl.structorInjectionTest.StudyDemo">
5         <constructor-arg ref="math"/>
6         <constructor-arg ref="english"/>
7     </bean>
構造註入xml書寫

代碼書寫:

技術分享圖片
 1 public class EnglishDemo {
 2     public void StudyEnglish(){
 3         System.out.println("學習英語。。。。");
 4     }
 5 }
 6 
 7 
 8 public class MathDemo {
 9     public void StudyMath(){
10         System.out.println("學習數學。。。。");
11     }
12 }
13 
14 public class StudyDemo {
15     private MathDemo mathDemo;
16     private EnglishDemo englishDemo;
17 
18     //無參構造方法
19     public StudyDemo() {
20     }
21 
22     public StudyDemo(MathDemo mathDemo, EnglishDemo englishDemo) {
23         this.mathDemo = mathDemo;
24         this.englishDemo = englishDemo;
25     }
26 
27 
28     public void study() {
29         mathDemo.StudyMath();
30         englishDemo.StudyEnglish();
31     }
32 }
構造註入代碼

備註:Spring通過JavaBean的無參構造函數實例化對象,當編寫了帶參的構造方法後,虛擬機不會再提供無參構造方法,為了保證使用,需要自行添加無參構造方法

3.3p命名空間註入

使用前添加聲明:xmlns:p="http://www.springframework.org/schema/p"
xml寫法:
<bean id="IocTest" class="com.one.ssm.impl.setterInjectionTest.IocTest"
p:zhangGa="三天不打鬼子,手都癢癢"
p:rod="世界上有2種人,認識2進制和不認識2進制的人"/>
語法:p:屬性名="屬性值"
引用:p:屬性名-ref="bean的Id"

(4)註入過程子標簽的使用

public class User {
    private String string;
    private List<String> list;
    private Set<String> listString;
    private Map<String,String> map;

  子標簽註入:

技術分享圖片
 1 <bean id="user" class="com.one.ssm.impl.collectionPropertyInjection.User">
 2         <!--list或者數組類型的屬性可以用<list>標簽註入-->
 3         <property name="list">
 4             <list>
 5                 <!--定義list數組中的元素-->
 6                 <value>足球</value>
 7                 <value>籃球</value>
 8             </list>
 9         </property>
10 
11         <property name="listString">
12             <!--set類型的集合屬性可以用<set>-->
13             <set>
14                 <value>足球</value>
15                 <value>籃球</value>
16             </set>
17         </property>
18 
19         <property name="map">
20             <map>
21                 <!--定義map中的鍵值對,如果鍵值對是bean對象,把value換成ref-->
22                 <entry>
23                     <key>
24                         <value>football</value>
25                     </key>
26                     <value>足球</value>
27                 </entry>
28             </map>
29         </property>
30 
31         <property name="mapString">
32             <!--Properties類型的屬性用<props>,是簡化了的 <map> 只能指定 String 類型的鍵和值-->
33             <props>
34                 <prop key="football">足球</prop>
35             </props>
36         </property>
37 
38         <!--註入空字符串-->
39         <!--<property name="string"><value></value></property>-->
40         <!--註入空值-->
41         <property name="string"><null/></property>
42     </bean>
xml書寫

(5)備註:

 5.1 在子標簽中有特殊符號需要轉換為實體:

  <:&lt;
  >:&gt;
  &:&amp;
  ‘:&aops;
  ":&quot;

例如:P&G應該寫成: P&amp;G 或者使用<![CDATA[]]>形式: <![CDATA[P&G]]>

例如:錯誤:<value>P&G</value>,正確:<value><![CDATA[P&G]]></value>或<value>P&amp;G</value>

加載註解定義的bean組件:<context:component-scan base-package="service,dao"> 在使用註解之後,需要使用component-scan標簽掃描註解標註的類,base-package指定需要掃描的基準包,多個包可以使用逗號(,)分開

5.2 使用註解實現IOC:

@Autowired:采用按照類型匹配的方式自動註入,可以省略setter方法,eg: @Autowired private UserDao dao;@Qualifier:如果有多個類型相匹配時,加入,eg: @Autowired @Qualifier("UserDao") private UserDao dao;
@Autowired:
-->對方法或者構造方法的入參就行標註
@Autowired public void setDao(@Qualifier UserDao dao){this.dao=dao}
-->對類中集合類型的成員變量進行標註
@component public class TaskQeue{@Autowired private List<Job> toDoList}:Spring會將Job類型的組件註入到toDoList
@Resource:有一個name屬性值,spring解釋為要註入的Bean的名稱,eg:@Resource(name="userDao")private UserDao dao;
如果沒有指定名稱,@Resource將根據字段名或者setter方法名產生默認的名稱。

5.3 spring中Bean的五個作用域:

singleton:默認值,容器中該Bean的實例只有一個
prototype:每次從容器中獲取Bean時,都會創建一個新的實例,存在線程安全的組件使用
request:用於Web應用環境,針對每次HTTP請求都會創建一個實例
session:用於Web應用環境,同一個會話共享一個實例
global session:僅在porlet的Web應用中使用,同一個全局會話共享一個實例,非porlet環境,等同於session
xml配置為:
<bean id="..." class="..." scope="..."> .... </bean>
-->使用註解指定Bean的作用域
@scope("prototype")
@Service
public class UserService(){}

5.4 基於xml配置spring的自動裝配

傳統:
<bean id="dao" class="com.one.ssm.dao.impl.UserDaoImpl"/>
<bean id="service" class="com.one.ssm.impl.aopTest.UserServiceImpl">
<property name="userDao" ref="dao"></property></bean>


自動裝配:

代替了通過property標簽顯示的指定Bean的依賴關系
<bean id="userMapper" class="com.one.ssm.dao.impl.UserDaoImpl"/>
<bean id="service" class="com.one.ssm.impl.aopTest.UserServiceImpl" autowire="byName"/>
備註:一般都會通過註解@Autowire來實現

以上為個人理解,僅供參考!!!

SpringIOC的概念理解、構造器註入、setter註入、p命名空間註入、IOC容器介紹與比較