依赖注入DI 控制反转IOC概念
控制反转IOC
- 什么是控制反转?简单来说,从主动变被动就是控制反转
- 控制反转是一个很广泛的概念,依赖注入是控制反转的一个例子
- 传统的程序开发,人们总是从主函数开始,调用各种各样的库来完成一个程序。这样的开发。开发者控制着整个运行过程。而现在人们使用框架开发,使用框架时,框架控制着整个运行过程
- 享受框架带来的福利的同时,就要遵循框架的规则。可以说,控制反转是所有框架最基本的原则,也是框架和普通类库最大的不同点
- 控制反转还有一个漂亮的比喻,好莱坞原则,Don’t call us,we’ll call you。事实上,不只是电影行业,基本上所有公司人力资源部对面试者都会说类似的话,让面试者从主动联系转换为被动等待
控制反转不是什么技术,而是一种设计思想。理解好IOC的关键在于要明确“谁控制谁,控制什么,为何是反转,什么是正转,那些方面反转了”
IOC的实现方式包括工厂模式,服务器定位模式,依赖注入DI
依赖注入 Dependency Injection
Task与特定实例绑定或与特定类型绑定或与特定接口绑定,灵活性、可扩展性是依次提高的。
package cn.tx.demo3; /*案例 把任务指派某个程序员完成*/ public class Task { private String name; private Phper person; public Task(String name){ this.name=name; this.person=new Phper("李四"); } public void start(){ System.out.println(this.name+"开始工作"); this.person.writeCode(); } } class Phper{ private String name; public Phper(String name){ this.name=name; } public void writeCode(){ System.out.println(name+"phper正在写代码"); } } //测试类的代码 public class demo_1 { public static void main(String[] args) { Task lisi = new Task("4亿买卖任务"); lisi.start(); } }
/*案例 把任务指派某个程序员完成*/ public class Task1 { private String name; private Phper1 person; public Task1(String name){ this.name=name; // this.person=new Phper("李四");构造器里面的指定的人抽取出来 } /*用户可以自己指派人*/ public void setPerson(Phper1 person){ this.person=person; } public void start(){ System.out.println(this.name+"开始工作"); this.person.writeCode(); } } class Phper1{ private String name; public Phper1(String name){ this.name=name; } public void writeCode(){ System.out.println(name+"phper正在写代码"); } } //测试类 public class demo_2 { public static void main(String[] args) { Task1 task1 = new Task1("5亿大项目任务"); task1.setPerson(new Phper1("张三")); task1.start(); /*换一个人也很简单*/ task1.setPerson(new Phper1("李四")); task1.start(); } }
public interface Coder { void writeCode(); } public class Task2 { private String name; private Coder person; public Task2(String name){ this.name=name; // this.person=new Phper("李四");构造器里面的指定的人抽取出来 } /*用户可以自己指派人*/ public void setPerson(Coder person){ this.person=person; } public void start(){ System.out.println(this.name+"开始工作"); this.person.writeCode(); } } class Phper2 implements Coder{ private String name; public Phper2(String name){ this.name=name; } public void writeCode(){ System.out.println(name+"phper正在写代码"); } } class Javaer2 implements Coder{ private String name; public Javaer2(String name){ this.name=name; } public void writeCode(){ System.out.println(name+"javaer正在写代码"); } } public class demo_3 { public static void main(String[] args) { Task2 task2 = new Task2("10亿项目"); task2.setPerson(new Javaer2("小磊")); task2.start(); /*这种方式就可以变换程序员类型或者具体程序员的名字都可以了*/ } } //输出结果:10亿项目开始工作小磊javaer正在写代码10亿项目开始工作小辰phper正在写代码
依赖注入实现了控制反转的思想
依赖注入对我们的帮助体现在:
- 松耦合,高内聚。
- 可重用组件,可测性,更加轻盈的代码。
Java中依赖注入的几种方式
通过set方法注入,就是上面代码利用的方式。
public class Task(){ private ClassB classb; public void setClassB(ClassB b){ ClassB = b; } }
通过构造器注入
public class Task(){ private ClassB classb; public Task(ClassB classb){ this.classb = classb; } }
通过注解注入
@inject//依赖注入框架