Java的DI依赖注入
对我来说比较新的一个概念,以前还真没有接触过。所以简单总结总结。
不适用依赖注入的情况
// 接口
public interface GreetingService {void greet();
}// 实现类
public class EnglishGreeting implements GreetingService {public void greet() {System.out.println("Hello!");}
}// 使用者类
public class Client {private GreetingService service;public Client() {// 写死了具体实现this.service = new EnglishGreeting(); // 强耦合}public void sayHello() {service.greet();}
}// main 方法
public class Main {public static void main(String[] args) {Client client = new Client();client.sayHello(); // 输出:Hello!}
}
使用依赖注入的情况。
// 接口
public interface GreetingService {void greet();
}// 实现类
public class EnglishGreeting implements GreetingService {public void greet() {System.out.println("Hello!");}
}// 使用者类,不管 new,交给容器
public class Client {@Resourceprivate GreetingService service;public void sayHello() {service.greet();}
}// 模拟注入容器
public class BeanFactory {private Map<String, Object> beans = new HashMap<>();public void register(String name, Object bean) {beans.put(name, bean);}public void inject(Object target) throws Exception {Class<?> clazz = target.getClass();for (Field f : clazz.getDeclaredFields()) {if (f.isAnnotationPresent(Resource.class)) {Object bean = beans.get(f.getName());f.setAccessible(true);f.set(target, bean);}}}
}// main 方法
public class Main {public static void main(String[] args) throws Exception {BeanFactory factory = new BeanFactory();factory.register("service", new EnglishGreeting());Client client = new Client();factory.inject(client); // 自动注入client.sayHello(); // 输出:Hello!}
}
@Resource修饰成员变量,只要成员变量名是register的名字,就自动初始化成注册的bean。@Resource修饰方法,是根据方法的参数名来匹配。比如:
@Resource
public void setZhService(GreetingService zhService) {
this.zhService = zhService;
}
这里就会用zhService去查找之前的register。
最后的f.set(target, bean);// 其实就相当于 client.service= EnglishGreeting;
其实从比对可以看出,就是把bean保存在Map<String, Object> beans里面。通过String去查找具体要用什么类。
好吧,感觉就是继续解耦了一些,把很多实现类由一个map统一管理而不是自己管理了。
具体有什么好处以后再看吧。。。