今日份学习: Spring - 事实标准

笔记

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);
            }
        });
    }
}
posted @ 2020-02-18 13:57  带了1个小才艺  阅读(186)  评论(0)    收藏  举报