笔记
Spring IOC
Inverse of Control:控制反转
DI:Dependancy Injections:依赖注入
没有IOC的时候,各种依赖需要逐个按顺序创建。
有了IOC的之后,只要告诉那个依赖那个就可以了,容器会自动装配好依赖
手写一个IOC容器
public class MyIoCContainer {
// 实现一个简单的IoC容器,使得:
// 1. 从beans.properties里加载bean定义
// 2. 自动扫描bean中的@Autowired注解并完成依赖注入
public static void main(String[] args) {
MyIoCContainer container = new MyIoCContainer();
container.start();
OrderService orderService = (OrderService) container.getBean("orderService");
orderService.createOrder();
}
private static Map<String, Object> beans = new HashMap<>();
// 启动该容器
public void start() {
Properties properties = new Properties();
try {
properties.load(MyIoCContainer.class.getResourceAsStream("/beans.properties"));
properties.forEach((beanName, beanClass) -> {
try {
Class<?> klass = Class.forName(String.valueOf(beanClass));
Object beanInstance = klass.getConstructor().newInstance();
beans.put(String.valueOf(beanName), beanInstance);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
beans.forEach((beanName, beanInstance) -> dependencyInject(beanName, beanInstance, beans));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 从容器中获取一个bean
public Object getBean(String beanName) {
return beans.get(beanName);
}
private static void dependencyInject(String beanName, Object beanInstance, Map<String, Object> beans) {
List<Field> fieldsToBeAutowired = Stream.of(beanInstance.getClass().getDeclaredFields())
.filter(field -> field.getAnnotation(Autowired.class) != null)
.collect(Collectors.toList());
fieldsToBeAutowired.forEach(field -> {
try {
String fieldName = field.getName();
Object dependencyBeanInstance = beans.get(fieldName);
field.setAccessible(true); //打破封装性,访问私有成员方法或变量
field.set(beanInstance, dependencyBeanInstance);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
});
}
}