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

一、IOC概念理解

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

  DI(Dependency Injection)即「依賴注入」:由容器動態的將某個依賴關係注入到組件之中。依賴注入的目的並不是爲軟件系統帶來更多功能,而是爲了提高組件重用的頻率,併爲系統搭建一個靈活、可擴展的平臺。web

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

(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書寫

代碼書寫:session

 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的無參構造函數實例化對象,當編寫了帶參的構造方法後,虛擬機不會再提供無參構造方法,爲了保證使用,須要自行添加無參構造方法app

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;ide

例如: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來實現

以上爲我的理解,僅供參考!!!

相關文章
相關標籤/搜索