Spring的IOC控制反轉(zhuǎn)和DI依賴注入到底有什么意義

1.IOC和DI概念意義和實現(xiàn) :
馬克- to-win:馬克 java社區(qū):防盜版實名手機(jī)尾號: 73203。
馬克-to-win:由于控制反轉(zhuǎn)和依賴注入的概念比較難,我們拿下面這個例子來講解概念。我們過去在學(xué)mvc時,都是在controller里實例化出一個service的對象,之后再使用它。實例化對象的控制權(quán)在我們手里(所謂正序)。現(xiàn)在當(dāng)我們應(yīng)用spring容器時,實例化的控制權(quán)不在我們手里了,控制權(quán)反轉(zhuǎn)了,控制權(quán)利跑到spring容器手里了。@Service的意思就是把實現(xiàn)這個接口類型的類實例化以后放在spring容器當(dāng)中,供將來使用(不懂就看我的例子)。(注意,如果有兩個類都實現(xiàn)了接口,而且都有@Service關(guān)鍵字,就會報錯,容器不知道將來用誰)。既然@Service是實例化的意思,@Resource就是引用實例的作用。控制反轉(zhuǎn)講了,下面講講依賴注入。還拿下面這個例子來講。 controller想干活就需要引用service,專業(yè)一點(diǎn)講,叫依賴service。換句話說,controller想干活,需要把它依賴的 service注入進(jìn)來,這叫依賴注入。靠什么呢?就靠上述@Resource或@Autowired的關(guān)鍵字。

有同學(xué)說,這折騰什么呢?有什么意義?。縤oc到底有什么好處?還拿咱們例子說事。如果現(xiàn)在新的需求下來,需要改動我們的 service,連名字帶包名,都得改,而且還要求controller不能改。這在過去,用new關(guān)鍵字實例化時,controller是肯定要改動的,因為是硬編碼(new Service)。而現(xiàn)在是用控制反轉(zhuǎn),你看一下代碼,果然即使service名字都變了的情況下,controller都不用改,程序依然運(yùn)行良好。(順便提一句,想達(dá)到這種效果必須用接口編程,見我們的例子。不用接口編程,雖然程序還是能夠通,但實現(xiàn)不了controller不變的目標(biāo),即,達(dá)不到 controller和service像現(xiàn)在用接口編程這樣高度的松耦合。接口完全把依賴別人者和被依賴者分開了。依賴別人者只對接口說話,連被依賴者改變與否都不知道。達(dá)到了高度的松耦合。只要接口不改,controller就不改,接口就像合同,我講過,在接口那章,記得嗎?)一句話,控制反轉(zhuǎn)的好處就是,當(dāng)與接口編程同時使用時,依賴別人者不會因被依賴者改變而改變,達(dá)到了高度的松耦合。





例 1.1

<%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
    <title>Spring 3.0</title>
</head>
<body>
    <a href="helloa.do">點(diǎn)擊跳轉(zhuǎn),你好,馬克-to-win</a>
</body>
</html>


    <context:component-scan
        base-package="com" />
    <context:component-scan
        base-package="service" />


package com;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import service.interfac.ILoginService;

@Controller
public class HelloWorldController {
    @Resource
    private ILoginService loginServic;

    @RequestMapping("/helloa")
    public ModelAndView helloWorld() {
        loginServic.login();
        System.out.println("after loginServic.login()");
        return new ModelAndView("/helloq", "message", "你好");
    }
}


package service.interfac;
public interface ILoginService {
    public void login();
}






package service;
import org.springframework.stereotype.Service;
import service.interfac.ILoginService;
@Service
public class LoginServiceImpl implements ILoginService {
    public void login() {
        System.out.println("LoginServiceImpl");
    }
}



當(dāng)新需求改變時,我們把上面的service文件改成下面的service文件,controller不用改變,程序照樣能正常運(yùn)行。

package service;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import service.interfac.ILoginService;

@Service
public class LoginServiceImpl2 implements ILoginService {
    public void login() {
        System.out.println("LoginServiceImpl2");
    }
}