Spring IOC和DI

控制反轉IOCjava

例子:spring

你想吃麪包,這時候有兩種狀況:編程

1 你家附近沒有面包店,你就要本身買原材料本身作麪包(傳統編程模式:須要本身new對象)app

2 你家附近有面包店,那麼你只要把你想要吃的口味告訴店家,一會你就能夠吃到麪包了(控制反轉:本身不new對象,對象由框架交給你)框架

注意:你沒有製做麪包,而是由店家制做麪包,可是徹底符合你的口味測試

控制反轉:就是對象由Spring容器建立和管理,調用者只負責使用,下降耦合度,控制權由調用者轉移到Spring容器,控制權產生了反轉。this

依賴注入:從Spring容器角度來看,Spring容器負責將被依賴對象賦值給調用者的成員變量,至關於爲調用者注入它所依賴的實例。spa

因此,控制反轉是一種經過描述(Spring中能夠是XML文件或註解)並經過第三方去產生或獲取特定對象的方式。設計

Spring中實現控制反轉的是IOC容器,其實現方式是依賴注入(DI)code


 

IOC容器的設計主要是基於BeanFactory和ApplicationContext兩個接口

applicationContext.xml

<bean id="test" class="dao.TestDaoImpl" />

dao/ITestDao.java(接口)

package dao;

public interface ITestDao {
    public void sayHello();
}

dao/TestDaoImpl.java(實現類)

package dao;

public class TestDaoImpl implements ITestDao{

    public void sayHello() {
        // TODO Auto-generated method stub
        System.out.println("Hello,Study hard!");
    }
    
}

test/Tests.java(測試類)

package test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import dao.ITestDao;

public class Tests {
    
    @Test
    public void test1() {
        //初始化spring容器ApplicationContext,加載配置文件
        ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
        //經過容器獲取test實例
        ITestDao tt = (ITestDao) appCon.getBean("test");
        tt.sayHello();
    }
}

 


 

依賴注入(DI)

依賴注入是Spring中實現IOC容器的方法,其做用是在使用spring框架建立對象時動態的將其所依賴的對象或屬性值注入bean組件中

依賴注入一般使用兩種方式實現:構造方法注入和setter方法注入


1.構造方法注入

applicationContext.xml內容

<!-- 將指定類DIServiceImpl配置給spring,讓spring建立其實例 -->
<bean id="myTestDao" class="dao.TestDaoImpl"></bean>
<!-- 使用構造方法注入 -->
    <bean id="diService" class="service.DIServiceImpl"> <!-- 將myTestDao注入到DIServiceImpl類的屬性ITestDao上 --> <constructor-arg index="0" ref="myTestDao" /> </bean>

service.IDIService.java

package service; /** * 使用構造方法依賴注入ITestDao接口對象 * * Title: IDIService * * Description: * * @author Ethan * * @date 2019年6月25日 * */ public interface IDIService { public void sayHello(); }

service.DIServiceImpl.java

package service; /** * IDIService接口的實現類 * * Title: DIServiceImpl * * Description: * * @author Ethan * * @date 2019年6月25日 * */ import dao.ITestDao; public class DIServiceImpl implements IDIService{ private ITestDao iTestDao; //構造方法,用於實現依賴注入接口對象iTestDao public DIServiceImpl(ITestDao iTestDao) { super(); this.iTestDao = iTestDao; } public void sayHello() { //調用iTestDao中的sayHello方法  iTestDao.sayHello(); System.out.println("IDIService構造方法注入"); } }

測試類:

test.Tests2.java

package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import service.IDIService; public class Tests2 { /** * 構造方法注入測試類 * * Title: Test1 * * Description: * * */ @Test public void Test1() { ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml"); IDIService ts = (IDIService) appCon.getBean("diService"); ts.sayHello(); } }

運行結果:

Hello,Study hard!
IDIService構造方法注入

 


 

2 setter方法注入

在上面的結構中加入service.DIServiceImpl.java

package service; import dao.ITestDao; public class DIServiceImpl1 implements IDIService{ private ITestDao iTestDao; //添加iTestDao的setter方法,用於實現依賴注入 public ITestDao getiTestDao() { return iTestDao; } public void setiTestDao(ITestDao iTestDao) { this.iTestDao = iTestDao; } public void sayHello() { // TODO Auto-generated method stub //調用iTestDao中的sayHello方法  iTestDao.sayHello(); System.out.println("TestDaoImpl setter方法注入"); } }

applicationContext.xml加入

<!-- 使用setter方法的注入 -->
    <bean id="testDIService1" class="service.DIServiceImpl1">
        <!-- 調用DIServiceImpl1類的setter方法,將myTestDao注入到DIServiceImpl1類的屬性iTestDao上 -->
        <property name="iTestDao" ref="myTestDao" />
    </bean>

測試類:Tests2.java中加入

/** * 使用setter方式注入測試類 * * Title: Test2 * * Description: * * */ @Test public void Test2() { ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml"); IDIService ts = (IDIService) appCon.getBean("testDIService1"); ts.sayHello(); }

運行結果:

Hello,Study hard!
TestDaoImpl setter方法注入

 


 

 

思考

1 IOC容器的實現方式有哪些?

2 在spring框架中什麼是控制反轉?什麼是依賴注入?使用控制反轉與依賴注入有什麼優勢?

3 spring框架採用java的什麼機制進行依賴注入

相關文章
相關標籤/搜索