淺談spring框架的控制反轉和依賴注入


spring是什么?

spring是一個輕量級的控制反轉和面向切面編程的開源容器框架。

輕量級是說spring框架本身的體積小。

控制反轉(Ioc):它不是技術,而是一種思想,將創建對象的控制權力交給spring框架。

依賴注入(DI):指Spring創建對象的過程中,將對象依賴的屬性(簡單值,集合,對象)通過配置的方式進行設值。

IoC和DI其實是同一個概念的不同角度描述,DI相對IoC而言,明確描述了被管理的對象中,依賴的屬性也應該由Spring容器自動注入

面向切面編程(AOP):零散存在於業務層中的功能代碼(例如:日志,事務),稱為橫切面關注點。把一個個橫切面關注點放到某個模塊中,稱為切面。

AOP就是把多個方法前后的共同代碼抽離出來,使用動態代理機制來控制。好處是降低耦合度,減少重復代碼,提高代碼的可擴展性和可維護性。

 

Ioc容器

spring的容器對象有BeanFactory和ApplicationContext。

BeanFactory和ApplicationContext的區別:

BeanFactory是spring的最頂層的接口,而ApplicationContext繼承了BeanFactory,常用的實現類是ClassPathXmlApplicationContext。

BeanFactory創建對象是在需要對象bean的時候才會創建,而ApplicationContext創建對象的時機是在加載容器時就會創建出所有的bean。

使用xml方式創建對象:

在spring配置文件中創建<bean></bean>標簽,設置相應id和class屬性。

<?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="user" class="com.myspring.user.User">
    </bean>

</beans>

 

使用注解方式創建對象:

Ioc創建對象的注解有四個:@component,@controller,@service,@repository

它們的作用都是把被貼上注解的類交給spring管理,由spring自動的創建對象。

區別是:@controller用於標注控制層組件,@service用於標注業務層組件,@repository用於標注數據訪問組件,也就是DAO組件,當組件不好歸類時使用@component。

 

使用Ioc注解的前提:配置文件中要有Ioc注解解析器,在配置文件中加一行配置<context:component-scan base-package="com.spring.mybackage">,base-package告訴spring去哪些包里面掃描bean,如果有多個包需要被掃描,用逗號分開即可。如果是一些沒有源碼的類,比如框架內部定義好的類,就只能通過xml方式,不能用注解方式,因為我們改變不了那些源代碼。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="classpath:db.properties"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <context:component-scan base-package="com.myspring.login"/>

</beans>

IoC的注解方式可以認為是代替了原來在配置文件中配置的<bean id="user" class="com.myspring.user.User"></bean>標簽。

依賴注入DI

在spring創建對象的過程中,需要將對象依賴的屬性也自動的進行賦值,並且如果使用DI為A對象注入B對象,那么需要A和B都在spring容器中。

setter注入方式(前提屬性必須有set方法)

在xml配置文件的<bean></bean>標簽中手動配置一個<property></property>標簽,<property>有兩個屬性。name屬性的值就是對象中屬性的名字。注入值需要先判斷該屬性的數據類型。

如果是簡單數據類型,使用value屬性進行注入(setter注入方式本質是在執行set方法,如果對象的屬性名字是abc,那么spring會自動找setAbc方法,跟對象中是否有這個字段無關。並且spring在注入值時隱含着類型轉換,可以自動把string類型轉換成Integer)。

如果是引用數據類型,使用ref=""引用一個對象,引用數據類型ref的值是spring容器中已經存在的對象的id值。

如果是集合數據類型,就要使用集合各自對應的標簽進行注入。(注意:注入集合類型的數據時,集合的泛型會影響輸出的結果)。

 <bean id="user" class="com.myspring.user.User">
        <property name="name" value="張三"></property>
        <property name="age" value="20"></property>
 </bean>

構造器注入方式

對象中必須存在有參構造,哪些屬性需要注入值,構造函數就要有對象的參數,和setter方式類似,只需要將<property>標簽替換為<constructor-arg>標簽。<constructor-arg>標簽中的name屬性的值要和有參構造中的形參一致。

<bean id="user" class="com.myspring.user.User">
        <constructor-arg name="name" value="jack"/>
        <constructor-arg name="age" value="18"/>
</bean>

使用注解的注入方式

DI注解可以認為是代替了原來在配置文件中配置的<property name="name" value="張三"></property>標簽。

在spring中使用注解方式完成DI操作,一是使用spring自帶的@Autowired,二是使用JavaEE規范提供的注解@Resource。二者功能相同。

@Autowired可以讓spring自動的把對象需要的屬性從spring容器中找出來,並注入給該屬性。@Autowired可以貼在字段或者set方法上,但一般貼在字段上,因為使用@Autowired沒有set方法也可以注入,但是@Autowired的底層還是使用了setter方式注入。

@Autowired和@Resource的區別

@Autowired會先按照依賴對象的類型找,沒有找到默認會報錯,如果找到一個,直接注入;如果在spring容器中找到多個匹配的類型,再按照名字找,沒有找到會報錯。

@Resource會先按照名字找,沒有找到才會按照類型去找。

為什么DI注解不需要注解解析器?

spring容器在啟動時會自動加入解析器,所以注解會生效。DI注解解析器是<context:annotation-config/>,但是在spring3.0之前,需要手動配置DI注解解析器。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM