zoukankan      html  css  js  c++  java
  • 依赖注入与控制反转

    记得大学开的有一门课是软件工程,而且还是两个学期,可能实践的机会少有的理论可能也只是记住的,比如软件设计的六大原则:单一原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开闭原则,但没真正的理解明白为什么要这样。现在毕业也3年多了,项目也接触了几个,还有一些开源的框架,记得在中软给华为做外包时帮悍马其他组的支援了几天,当时还不知道ABP框架,对IOC也只是听说过,并没有理解。当接触了ABP框架才发现,原来当时做的项目就是采用的ABP框架啊。其实像这些设计原则、还有模式这些,主要还是为了系统的高内聚,低耦合。最近在自学javaweb,学javaweb自然不能少了spring,spring的核心就是IOC和AOP,今天主要来说下IOC——Inversion of Control/控制反转。

    一、依赖注入DI—Dependency Injection

    1.依赖

    在说IOC之前先聊下依赖注入,依赖注入可以分两部分一是依赖二是注入。那什么是依赖?不是我自身的但没有就活不下去,人没了空气、水、阳光,那就活不下去。所以人依赖空气、水、阳光。下面代码定义了一个Person和一个CleanAir的类,Person依赖CleanAir。

    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接口的对象就可以,只是我们这是手动的给,这有点类似代理设计模式,要给代理设置具体对象。

    二、控制反转 IOC——Inversion Of Control

    上面依赖注入分两部分,当然控制反转也可分两部分。一是控制二是反转。

    1.控制

    像上面的不管是直接在Person中生命CleanAir属性还是创建一个接口,都是需要在程序New()一个对象出来,是程序控制Air.而IOC呢,它有专门的容器来管理这些对象,控制着他们的创建及生命周期,只要配置下,不用我们在new了。下次如果有CoolAir(冷空气),那只需要增加一个类CoolAir并实现IAir接口就行,然后在配置文件中配置一下,这样多省事。

    2.反转

    有反转那就有正转。上面的那种通过new来获取依赖的对象,是对象主动找依赖的对象,而IOC是管理着依赖的对象,然后给对象找它所对应的依赖的对象并注入。获取依赖对象的方式改变了,一个是主动一个是被动的。而Spring就是提供了自动注入依赖的功能。

    三、个人理解

    依赖注入手动注入依赖也算是依赖注入,控制反转呢算是自动注入依赖。手动注入还是需要new来创建对象,还是适应不了以后的变化,控制反转算是更加包容,不需要new创建,只要实现某个接口,IOC会自动注入。如果再往下一步思考,IOC配置的依赖在XML中,Xml中保存的内容都可以理解为字符串,怎么让字符串转换成对象呢,那就需要用到反射。其实这些不管是Java还是C#,思想都是一样的,不管那门语言,只要理解了思想,学习起来也不难,很容易就能上手。

     四、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。

  • 相关阅读:
    智慧养老民政监管平台建设方案
    CF600E Lomsat gelral dsu on tree
    dsu on tree详解
    【Spring 从0开始】Spring5 新功能,整合日志框架 Log4j2
    【Spring 从0开始】JdbcTemplate 数据库事务管理
    【Spring 从0开始】JdbcTemplate 数据库事务参数
    【Spring 从0开始】JdbcTemplate 数据库事务管理
    【Spring 从0开始】JdbcTemplate 操作数据库
    【Spring 从0开始】AOP 操作
    【Spring 从0开始】AOP 操作中的相关术语、环境准备
  • 原文地址:https://www.cnblogs.com/5ishare/p/7774624.html
Copyright © 2011-2022 走看看