对我来说比较新的一个概念,以前还真没有接触过。所以简单总结总结。
不适用依赖注入的情况
// 接口
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 {
@Resource
private 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统一管理而不是自己管理了。
具体有什么好处以后再看吧。。。