1. 程式人生 > >Spring IOC和DI中及其註解詳解

Spring IOC和DI中及其註解詳解

一.IOC和DI
  1.IoC:指將物件的建立權,反轉給了Spring容器; 
  不是什麼技術,而是一種設計思想,好比於MVC。就是將原本在程式中手動建立物件的控制權,交由Spring框架來管理。
正控:若呼叫者需要使用某個物件,其自身就得負責該物件的建立。
反控:呼叫者只管負責從Spring容器中獲取需要使用的物件,不關心物件的建立過程,也就是把建立物件的控制權反轉給了Spring框架。
DI:Dependency Injection(依賴注入):
從字面上分析:

  2.DI :指Spring建立物件的過程中,將物件依賴屬性(簡單值,集合,物件)通過配置設值給該物件。
  IoC和DI其實是同一個概念的不同角度描述,DI相對IoC而言,明確描述了“被注入物件依賴IoC容器配置依賴物件”。
  3.Container:容器,在生活中容器就是一種盛放東西的器皿,從程式設計角度看作是裝物件的物件,
  因為存在對物件的存入、取出等操作,所以容器還要管理物件的生命週期。
  
二. DI注入方式


  1.物件注入(setter和構造器注入)
    手動裝配(XML bean方式)
    自動裝配(註解方式).
  2.屬性注入
    使用bean元素的<property>子元素設定;
        簡單型別值,直接使用value賦值;
        引用型別,使用ref賦值;
        集合型別,直接使用對應的集合型別元素即可。
    spring通過屬性的setter方法注入值;
    在配置檔案中配置的值都是string,spring可以自動的完成型別的轉換
    屬性的設定值是在init方法執行之前完成的

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="employee" class="com.shenzhenair.day01.property.Employee"  >
        <property name="id" value="1" />
        <property name="name" value="tom" />
        <property name="age" value="17" />
        <property name="address" value="深圳" />

    </bean>
    
    <bean id="collectionBean" class="com.shenzhenair.day01.property.CollectionBean"  >
        <property name="set">
            <set  >
               <value>set1</value>
               <value>set2</value>
               <value>set3</value>
            </set>
        </property>
        <property name="list">
            <list  >
               <value>list1</value>
               <value>list2</value>
               <value>list3</value>
            </list>
        </property>
        <property name="array">
           <list>
               <value>arr1</value>
               <value>arr2</value>
               <value>arr3</value>
           </list>
        </property>
        <property name="map">
            <map>
                <entry key="k1" value="v1" />
                <entry key="k2" value="v2" />
                <entry key="k3" value="v3" />
            </map>
        </property>
        <property name="pro">
            <props>
                <prop key="p1" >v1 </prop>
                <prop key="p2">v2</prop>
                <prop key="p3">v3</prop>
            </props>
        </property>
        
    </bean>
    
</beans>
@Setter
@Getter
public class Employee {
    private Long id;
    private String name;
    private Integer age;
    private String address;

}
@Setter
@Getter
public class CollectionBean {
    private Set<String> set;
    private List<String> list;
    private String[] array;
    private Map<String,Object> map;
    private Properties pro;

}

三.Spring提供的裝配標籤:
Autowired和Qualifier標籤:
1.通過@Autowired標籤可以讓Spring自動的把屬性需要的物件從Spring容器找出來,並注入給該屬性。
2.第三方程式:Spring3.0之前,需要手動配置@Autowired解析註解程式,Spring就會自動的加入針對@Autowired標籤的解析程式。
      從Spring3.0開始,可以不再需要改配置了。如果不在Spring的測試環境中,也找到@Autowired的解析程式碼,此時頁必須配置.
    <context:annotation-config />
[email protected]標籤貼在欄位或者setter方法上。
[email protected]可以同時為一個屬性注入多個物件。
      public void setXxx(OtherBean1 other1,OtherBean2 other2) {}
5.使用@Autowired標籤可以注入Spring內建的重要物件,比如BeanFactory,ApplicationContext。
  6.測試類:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration
    public class SpringTest {
        @Autowired
        private ApplicationContext ctx;
    }
6.預設情況下@Autowired標籤必須要能找到對應的物件。可使用required=false來避免該問題:@Autowired(required=false)
[email protected]找bean的方式:
    1)、首先按照依賴物件的型別找,如果找到則使用setter方法或者欄位直接注入;
    2)、如果在Spring上下文中找到多個匹配的型別,再按照名字去找,如果沒有匹配則報錯;
    3)、可以通過使用@Qualifier("otherBean")標籤來規定依賴物件按照bean的id+型別去找;
四.JavaEE提供的裝配標籤:
  @Resource標籤:
  [email protected]標籤是JavaEE規範的標籤;也可以作用於欄位或者setter方法;必須要求有匹配的物件;
  5.<context:annotation-config>既引入了@Autowired標籤的解析器,也引入了@Resource的解析器;
  [email protected]標籤找bean的方式:
    1),首先按照名字去找,如果找到,就使用setter或者欄位注入;
    2),如果按照名字找不到,再按照型別去找,但如果找到多個匹配型別,報錯;
    3),可以直接使用name屬性指定bean的名稱;但是,如果指定的name,就只能按照name去找,如果找不到,就不會再按照型別去找;
    
五.使用標籤簡化IoC:

1.使用標籤來完成IoC,就必須有IoC標籤的解析器:
    使用context:component-scan來掃描spring需要管理的bean
    base-package就告訴spring,去哪些包及其子包裡去掃描bean,如果有多個包需要被掃描;只需要用逗號隔開多個包即可
    <context:component-scan base-package="com.shenzhenair.service" />
2.標註Bean的註解:@Component
  預設情況,直接使用類的名字(首字母小寫作為bean的名字)
  如果要修改bean的名稱;直接使用value屬性來重新定義bean的名稱
  @Component("otherbean")
3.使用@Component的限制:
  1),不能運用到靜態工廠方法和例項工廠方法,但是可以使用到FactoryBean;
  2),對於沒有原始碼的類(框架內部的預定義類),只能用XML配置;
4.bean元件版型標籤
  bean元件版型:
  @Service用於標註業務層元件、
  @Controller用於標註控制層元件(如struts中的action)、
  @Repository用於標註資料訪問元件,即DAO元件。
  @Component泛指元件,當元件不好歸類的時候,我們可以使用這個註解進行標註。
5.指定bean的作用域:@Scope("prototype")
6.初始化和銷燬方法
  @PostConstruct
  public void init() {
  相當於<bean init-method="init" />
  @PreDestroy
  public void destory() {
  相當於<bean destroy-method="destory" />
7.選用xml還是註解:
  1),Annotation:使用方便,XML檔案很小,但是,依賴關係又重新回到了程式碼當中;
  2),XML:使用稍微複雜,但是,程式碼很乾淨,程式碼不會很任何框架產生關係;XML安全;