Spring環境搭建之:控制反轉(IoC Inversion of Control)與依賴注入(DI Depenency Injection)

控制反轉,要明白是控制什麼,怎麼反轉了就OK了
1.控制什麼
不用Spring框架時,每一個類文件中所用到的對象都要咱們在代碼中經過new來建立,這樣一來,在面向接口編程時,也要經過new來明確的建立一個接口實現類,雖是面向接口了,但是接口實現類已經肯定了,不能靈活更換其它實現類,這就產生了高耦合。
有了Spring框架,咱們就再也不須要在類文件中用new去建立對象了,也就根本不須要咱們去建立了,Spring經過配置文件來完成對象的建立。

到這應該明白,控制的是對象的建立 java

2.什麼反轉了
對象的控制權反轉了,原來是程序員經過new來完成對象的建立,而如今由Spring框架來完成。即對象的控制權轉變了。 程序員

applicationContext.xml的配置 spring

<?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="reportDao" class="com.bocloud.report.dao.ReportDao" />
</beans>

<bean id="" class="">部分就至關於ReportDao reportDao = new ReportDao();這樣Spring就能夠幫咱們建立一個名爲reportDao的對象,class要寫上帶完整包路徑的類名稱。其中的id能夠用name來替換,即
<bean name="" class="">,區別是name的值能夠帶有特殊字符。 數據庫

<bean id="" class="" scope="singleton|prototype|request|session">
scope能夠取4個值:singleton表示單例,生成的對象只有一個;prototype表示原型,每次生成的都是新的對象
不寫的時候默認是singleton apache

Spring建立好的對象,咱們能夠經過Spring的Bean工廠獲取: 編程

BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
ReportDao reportDao = factory.getBean("reportDao");
固然咱們通常不須要在類文件中去寫這些代碼,通常作單元測試時可使用以上方法。那Spring建立好的對象咱們怎麼拿來用呢?這就要說到依賴注入(DI)的功能了


依賴注入
通常一個類文件中須要用到其它類來,這就構成了依賴關係。如:ReportDao類中須要用到JdbcTemplate類完成數據庫的操做。這樣ReportDao就依賴JdbcTemplate,反過來JdbcTemplate就是RpeortDao的依賴。 session

public class ReportDao {
    private JdbcTemplate jdbcTemplate;

    private void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    
    // 其它代碼
}

要能在ReportDao中使用jdbcTemplate對象,須要在applicationContext.xml中(這裏沒有把PropertyPlaceholderConfiger加載屬性配置文件的配置信息寫上去,能夠參考http://my.oschina.net/u/1167544/blog/160713): app

<!-- 數據源配置, 使用DBCP數據庫鏈接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!-- 鏈接信息 -->
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="reportDao" class="com.bocloud.report.dao.ReportDao">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>

<property name="" ref="" />
name是對應的類的屬性,必須與類的屬性的名稱同樣,Spring會調用對應的setter方法
ref是調用setter方法時,傳入的參數,即要注入的對象,必須與<bean id="" />中的某一個id一致
如這裏,生成reportDao對象時,會調用setJdbcTemplate()方法,而這個方法要傳入一個JdbcTemplate對象,ref指向了jdbcTemplate,與<bean id="jdbcTemplate" />一致,就會將這個jdbcTemplate對象做爲參數傳入,並完成setJdbcTemplate()方法的執行,這樣ReportDao中的JdbcTemplate對象成功注入了。 框架

Spring還提供了其它的注入方法,最經常使用的就是上面的setter注入,其它的能夠參考spring文檔。 單元測試

依賴的自動注入,經常使用的有如下2種:
byName是根據set的名稱來注入,若是名稱不對就沒法注入(默認狀況)
byType表示是根據類型來注入,和名稱無關,若是一個類中有兩個相同類型的對象就沒法注入

1.經過配置文件實現自動注入
<bean id="" class="" autowire="byName|byType|default|construtor|no" />
給bean添加上autowire屬性就表示該bean的屬性能夠自動注入
若是入在<beans>上,則全部的bean屬性均可以自動注入

2.經過註解實現自動注入
這種狀況下配置文件中就能夠省掉<bean>,可是增長其它相應的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     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">
    <!-- 打開annotation的支持 -->
    <context:annotation-config/>
    <!-- 在哪一個包下掃描annotation -->
    <context:component-scan base-package="com.bocloud.report">
</beans>

類文件

@Component("reportDao") // 此註解就能按指定的名稱自動生成該類的對象,@Component時默認爲類名
public class ReportDao {
               // @Resource 自動注入,是按名稱,能夠放在字段上,也能夠放在setter方法上
    @Autowired //  此註解就能自動注入,是按類型,能夠放在字段上,也能夠放在setter方法上
    private JdbcTemplate jdbcTemplate;
    
    private void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    
    // 其它代碼
}
對於類上的註解@Component不一樣的類對應不一樣的註解,只是爲了區別開類的功能,固然統一使用@Component也行 因爲開發中通常都分爲四層體系:data、dao、service、action data------->@Component dao-------->@Repository service---->@Service action----->@Controller
相關文章
相關標籤/搜索