Функция внедрения зависимостей 30 классов рукописных основных принципов Spring (3)

Java Spring

Эта статья взята из «Основных принципов Spring 5».

В предыдущем анализе исходного кода мы узнали, что запись внедрения зависимостей (DI) — это метод getBean(), и был пройден основной процесс предыдущей рукописной части IoC. Сначала определите контейнер IoC в GPApplicationContext, а затем сохраните объект GPBeanWrapper на карте. Две карты разработаны в GPApplicationContext: factoryBeanObjectCache сохраняет кеш одноэлементных объектов, factoryBeanInstanceCache сохраняет кеш GPBeanWrapper, а имена переменных также соответствуют родному Spring, Дизайн этих двух объектов на самом деле является классическим приложением зарегистрированного одноэлементного шаблона. .


public class GPApplicationContext extends GPDefaultListableBeanFactory implements GPBeanFactory {

    private String [] configLocations;

    private GPBeanDefinitionReader reader;

    //用来保证注册式单例的容器
    private Map<String,Object> factoryBeanObjectCache = new HashMap<String, Object>();

    //用来存储所有的被代理过的对象
    private Map<String,GPBeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<String, GPBeanWrapper>();
		
    ...

}

1 Начните с метода getBean()

Начнем с усовершенствования метода getBean():


    @Override
    public Object getBean(String beanName) {

        GPBeanDefinition beanDefinition = super.beanDefinitionMap.get(beanName);

        try{

            //生成通知事件
            GPBeanPostProcessor beanPostProcessor = new GPBeanPostProcessor();

            Object instance = instantiateBean(beanDefinition);
            if(null == instance){ return  null;}

            //在实例初始化以前调用一次
            beanPostProcessor.postProcessBeforeInitialization(instance,beanName);

            GPBeanWrapper beanWrapper = new GPBeanWrapper(instance);

            this.factoryBeanInstanceCache.put(beanName,beanWrapper);

            //在实例初始化以后调用一次
            beanPostProcessor.postProcessAfterInitialization(instance,beanName);

            populateBean(beanName,instance);

            //通过这样调用,相当于给我们自己留有了可操作的空间
            return this.factoryBeanInstanceCache.get(beanName).getWrappedInstance();
        }catch (Exception e){
//            e.printStackTrace();
            return null;
        }
    }

2 метод instanceiateBean() для создания экземпляра


    //传一个BeanDefinition,就返回一个实例Bean
    private Object instantiateBean(GPBeanDefinition beanDefinition){
        Object instance = null;
        String className = beanDefinition.getBeanClassName();
        try{

            //因为根据Class才能确定一个类是否有实例
            if(this.factoryBeanObjectCache.containsKey(className)){
                instance = this.factoryBeanObjectCache.get(className);
            }else{
                Class<?> clazz = Class.forName(className);
                instance = clazz.newInstance();

                this.factoryBeanObjectCache.put(beanDefinition.getFactoryBeanName(),instance);
            }

            return instance;
        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }
		

3 Метод populateBean() завершает внедрение зависимостей


    private void populateBean(String beanName,Object instance){

        Class clazz = instance.getClass();

        if(!(clazz.isAnnotationPresent(GPController.class) ||
                clazz.isAnnotationPresent(GPService.class))){
            return;
        }

        Field [] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            if (!field.isAnnotationPresent(GPAutowired.class)){ continue; }

            GPAutowired autowired = field.getAnnotation(GPAutowired.class);

            String autowiredBeanName = autowired.value().trim();

            if("".equals(autowiredBeanName)){
                autowiredBeanName = field.getType().getName();
            }

            field.setAccessible(true);

            try {

                field.set(instance,this.factoryBeanInstanceCache.get(autowiredBeanName). getWrappedInstance());

            } catch (IllegalAccessException e) {
//                e.printStackTrace();
            }

        }

    }
		

4 постпроцессора GPBeanPostProcessor

BeanPostProcessor в родном Spring — это механизм обратного вызова, установленный для событий инициализации объекта. Эта мини-версия содержит только инструкции, а не конкретную реализацию. Заинтересованные «партнеры» могут продолжить углубленное изучение исходного кода Spring.


package com.tom.spring.formework.beans.config;

public class GPBeanPostProcessor {

    //为在Bean的初始化之前提供回调入口
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
        return bean;
    }

    //为在Bean的初始化之后提供回调入口
    public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
        return bean;
    }
}

До сих пор часть DI была завершена вручную, то есть основная часть Spring была завершена. Обнаружили ли «маленькие друзья», что это на самом деле очень просто?Следуйте «Архитектуре бомбы Тома» и ответьте «Весна», чтобы получить полный исходный код.

Эта статья является оригиналом "Архитектуры бомбы Тома", пожалуйста, указывайте источник при перепечатке. Технология заключается в обмене, я разделяю свое счастье! Если у вас есть какие-либо предложения, вы также можете оставить комментарий или личное сообщение, Ваша поддержка является движущей силой для меня, чтобы упорствовать в создании. Обратите внимание на «архитектуру бомбы Тома», чтобы получить больше технической галантереи!

Нелегко быть оригинальным, и круто настаивать. Вы все это видели здесь. Не забудьте поставить лайк, добавить в закладки, посмотреть и подписаться одним щелчком мыши! Если вы считаете, что контент слишком сух, вы можете поделиться им и отправить своим друзьям, чтобы они питались и питались!