依赖倒置,控制反转,依赖注入实现Spring容器的简单理解

依赖倒置,控制反转,依赖注入实现Spring容器的简单理解


依赖倒置 DIP
程序要依赖于抽象接口,不要依赖于具体实现
控制反转 Ioc
将new的任务交出去
依赖注入 DI
用了Ioc后,虽然不需要new,但还是需要使用实例,用到DI将实例注入到某个程序内

一丶理解DIP,Ioc,DI实例

class Comic{} //漫画类
class Novel{} //小说类
class Reader{
void read() {
   Comic comic=new Comic();
   book.show();
    }
}
Reader对象依赖于Comic对象,可是只需要使用Comic的对象,而在这里Reader对象负责Book对象的整个生命周期的管理,带来耦合度高,维护不好,假如Reader对象不想负责管理Comic对象的生命周期,怎么办?
使用 控制反转交给其他人来管理,再使用 依赖注入,只把Comic实例注入到Reader对象中
同时Reader对象又要看小说了,必须改代码 new Novel(),但是Reader对象不想改自己的代码,怎么办?
使用 依赖倒置让程序要依赖于抽象接口,不要依赖于具体实现,所以将Comic 和 Novel 抽象出一个Book类来传入

结合:控制反转,依赖注入 和 依赖倒置

class Book{}  //书籍抽象类
class Comic extends Book{} //漫画类
class Novel extends Book{} //小说类
class Reader{
Book book;
Reader(Book book){this.book=book;}
void read() {
   book.show();
    }
}
class Container{
  ClassName ProduceClass(String classname){
    //反射等等技术
    return classname;
  }
}

这时候Reader很开心

Reader reader=new Reader();
reader.read(Container.ProduceClass("Comic")); //读漫画
reader.read(Container.ProduceClass("Novel")); //读小说

小结:这只是一个很粗俗的模仿,控制反转,依赖注入是相辅相成的,你用了控制反转new的控制权交出去,你就需要依赖注入实例注入进去,而使用依赖倒置是为了程序的可扩展性。

补充:依赖注入的三种方法

前面这种是构造函数注入
public  class Reader{
private Book book;
Reader(Book book){this.book=book;}
public void read() {
   book.show();
    }
}
属性注入结合set
public  class Reader{
    private Book book;
    public void setBook(Book book){
       this.book=book;
    }
    public void read() {
        book.show();
    }
}
接口注入
public interface IRead{  
   void injectBook(Book book);  
}  
public class Reader implements IRead{  
    private  Book book;
    public void injectBook(Book book) {    
        this.book= book;         
    }  
   public void read() {
        book.show();
    }
}  

二丶Spring容器

依赖倒置,控制反转,依赖注入实现Spring容器的简单理解_第1张图片

如上图所示,SpringIoC是一个成熟的IoC容器,其实主要通过两个概念来实现IoC,通过Spring-config.xml配置文件,将对象和依赖对象都配置到XML文件中,然后通过架构中的上下文(context)类,来自动实现Ioc


三丶代码实例(IDEA)

①新建spring工程

依赖倒置,控制反转,依赖注入实现Spring容器的简单理解_第2张图片

②创建一下类,都在默认包中

  public class Book {
    public void Show(){}
}
public class Comic extends Book
{
    public  void Show()
    {
        System.out.println("Comic");
    }
}
public class Novel extends Book{
    public void Show()
    {
        System.out.println("Novel");
    }

} //小说类

public  class Reader{
    Book book;
    public void setBook(Book book){
       this.book=book;
    }
    public void read() {
        book.Show();
    }
}

③创建spring-config.xml


<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="Book" class="Book">bean>
    <bean id="Comic" class="Comic">bean>
    <bean id="Novel" class="Novel">bean>
    <bean id="Reader" class="Reader">
        <property name="Book" >
            <ref bean="Book">ref>
        property>
    bean>
beans>

④在Main函数或测试单中测试一下代码

// Spring体验
        System.out.println("Spring");
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
        Reader reader=(Reader) context.getBean("Reader");
        reader.setBook((Comic) context.getBean("Comic"));
        reader.read();
        reader.setBook((Novel) context.getBean("Novel"));
        reader.read();

⑤结果

在这里插入图片描述
成功


SSH系列入门链接

  1. Sturts2
  2. Spring 【当前】
  3. Hibernate

你可能感兴趣的:(Web开发,设计理念,#,后端)