依賴注入與控制反轉

記得大學開的有一門課是軟件工程,並且仍是兩個學期,可能實踐的機會少有的理論可能也只是記住的,好比軟件設計的六大原則:單一原則、里氏替換原則、依賴倒置原則、接口隔離原則、迪米特法則、開閉原則,但沒真正的理解明白爲何要這樣。如今畢業也3年多了,項目也接觸了幾個,還有一些開源的框架,記得在中軟給華爲作外包時幫悍馬其餘組的支援了幾天,當時還不知道ABP框架,對IOC也只是據說過,並無理解。當接觸了ABP框架才發現,原來當時作的項目就是採用的ABP框架啊。其實像這些設計原則、還有模式這些,主要仍是爲了系統的高內聚,低耦合。最近在自學javaweb,學javaweb天然不能少了spring,spring的核心就是IOC和AOP,今天主要來講下IOC——Inversion of Control/控制反轉。java

1、依賴注入DI—Dependency Injectionweb

1.依賴spring

在說IOC以前先聊下依賴注入,依賴注入能夠分兩部分一是依賴二是注入。那什麼是依賴?不是我自身的但沒有就活不下去,人沒了空氣、水、陽光,那就活不下去。因此人依賴空氣、水、陽光。下面代碼定義了一個Person和一個CleanAir的類,Person依賴CleanAir。apache

package com.cyw.Model;

public class Person {

    public Person(CleanAir air) {
        
        this.air = air;
    }
    CleanAir air;
}
View Code
package com.cyw.Model;

public class CleanAir {

}
View Code

 可是有這樣一句話世界上惟一不變的就是變化。以前乾淨的空氣不復存在,而Person依賴的不在是CleanAir,而是比CleanAir更有內涵的DirtyAir.若是仍是按照上面的方式來,那就須要在增長一個DirtyAir類的同時,還要修改Person,這種強依賴有很大的弊端,一個地方變化引發其餘地方也要修改,並且改變的只是Air,但Person也要改變。那怎麼樣能儘可能減小修改的地方呢?因而面向接口的編程出現了。下面是先定義一個接口IAir,類CleanAir實現接口IAir,在Person中不在直接依賴CleanAir,而是依賴接口IAir,這樣即便是DirtyAir也只須要修改給Person不一樣的Air就像了。編程

package com.cyw.Model;

public interface IAir {

}
View Code
package com.cyw.Model;

public class CleanAir implements IAir {

}
View Code
package com.cyw.Model;

public class Person {

    public Person(IAir air) {
        
        this.air = air;
    }
    IAir air;
}
View Code

2.注入設計模式

注入是啥?注入那它以前是沒有的,而是塞給它。上面實例化Person的時候咱們能夠塞給它一個只要實現IAir接口的對象就能夠,只是咱們這是手動的給,這有點相似代理設計模式,要給代理設置具體對象。框架

2、控制反轉 IOC——Inversion Of Controlmaven

上面依賴注入分兩部分,固然控制反轉也可分兩部分。一是控制二是反轉。ide

1.控制學習

像上面的不論是直接在Person中生命CleanAir屬性仍是建立一個接口,都是須要在程序New()一個對象出來,是程序控制Air.而IOC呢,它有專門的容器來管理這些對象,控制着他們的建立及生命週期,只要配置下,不用咱們在new了。下次若是有CoolAir(冷空氣),那隻須要增長一個類CoolAir並實現IAir接口就行,而後在配置文件中配置一下,這樣多省事。

2.反轉

有反轉那就有正轉。上面的那種經過new來獲取依賴的對象,是對象主動找依賴的對象,而IOC是管理着依賴的對象,而後給對象找它所對應的依賴的對象並注入。獲取依賴對象的方式改變了,一個是主動一個是被動的。而Spring就是提供了自動注入依賴的功能。

3、我的理解

依賴注入手動注入依賴也算是依賴注入,控制反轉呢算是自動注入依賴。手動注入仍是須要new來建立對象,仍是適應不了之後的變化,控制反轉算是更加包容,不須要new建立,只要實現某個接口,IOC會自動注入。若是再往下一步思考,IOC配置的依賴在XML中,Xml中保存的內容均可以理解爲字符串,怎麼讓字符串轉換成對象呢,那就須要用到反射。其實這些不論是Java仍是C#,思想都是同樣的,無論那門語言,只要理解了思想,學習起來也不難,很容易就能上手。

 4、Spring中使用Ioc的demo

上週四寫完以爲不完美,上面基本沒代碼,最好有demo,操做一下,這樣纔好,因此計劃着週六也就是今天上午來看下Spring的Ioc,可計劃趕不上變化,買的洗衣機到貨了,又是收快遞又是聯繫售後來安裝,一個上午就這麼沒了,因此趁着下午來看下spring。

1.建立maven project,選擇的是quickstart

2.建立接口層

這裏建立了兩個一個數據層一個服務層的接口層,並建立了兩個接口用來演示

IDao

package Cuiyw.Spring.IDao;

public interface IDao {

    public String sayHello(String name);
}
View Code

IService

package Cuiyw.Spring.IService;

public interface IService {

    public void service(String name);
}
View Code

 3.建立屬性層

根據上面的接口層建立了兩個實現層,並實現了上面的接口

DaoImpl

package Cuiyw.Spring.Dao;

import java.util.Calendar;

import Cuiyw.Spring.IDao.IDao;

public class DaoImpl implements IDao{

    public String sayHello(String name) {
        int hour=Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        if(hour<6) return "凌晨早,"+name;
        if(hour<12)return "早上好,"+name;
        if(hour<13)return "中午好,"+name;
        if(hour<18)return "下午好,"+name;
        return "晚上好,"+name;
            
    }    
}
View Code

ServiceImpl

package Cuiyw.Spring.Service;

import Cuiyw.Spring.IDao.IDao;
import Cuiyw.Spring.IService.IService;

public class ServiceImpl implements  IService{

    private IDao dao;
    public IDao getDao() {
        return dao;
    }
    public void setDao(IDao dao) {
        this.dao = dao;
    }
    public void service(String name) {
        System.out.println(dao.sayHello(name));
    }
}
View Code

4.引入spring

使用maven引入也很容易,在pom.xml中配置一下就能夠了。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>Cuiyw</groupId>
  <artifactId>SpringAop</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SpringAop</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <spring.version>5.0.0.RELEASE</spring.version>
  </properties>

  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
View Code

5.Ioc配置

要想讓spring自動注入,那也得讓spring知道要注入的是什麼。新建ApplicationContext.xml並進行下面的配置,具體配置是什麼意思,會在之後慢慢介紹。

<?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="DaoImpl" class="Cuiyw.Spring.Dao.DaoImpl"></bean>
<bean id="ServiceImpl" class="Cuiyw.Spring.Service.ServiceImpl">
<property name="dao" ref="DaoImpl"></property>
</bean>
</beans>
View Code

6.調用

在mian中經過xml獲取bean對象,而後調用裏面的方法。

package Cuiyw.SpringAop;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import Cuiyw.Spring.IService.IService;

public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"ApplicationContext.xml"});
        BeanFactory factory=context;
        IService service=(IService)factory.getBean("ServiceImpl");
        service.service("Cuiyw"); 
    }

}
View Code

7.項目結構

8.運行main方法

上面幾步算是簡單的實現了spring的ioc,但只是大概簡單的瞭解,並未深刻。咱們在mian中併爲進行new建立,而是經過spring來自動填充,找到對應的依賴注入給service。

相關文章
相關標籤/搜索