06 从迪迦(光、闪耀、火花)三种形态领悟的知识(实现Spring上下文,提供Bean创建的扩展)

前语

上一节,咱们现已完结通过 xml 配置文件 完结 Bean 的注入。这一节是重头戏,老实说,我现在都还弄的很理解。这是第二遍看这个进程了,仍是有点云里雾里的。可是相对于第一次来说,现已上升了一个高度。 在这一节,会对 spring 创立 bean 的进程进行封装。而且供给 BeanPostProcessor,BeanFactoryPostProcessor等扩展接口。(这两个东西老强了) 上下文把整个创立进程包装起来,对外暴露一个简单的入口,其他的东西都在内部完结。(这个进程其实能够类比成 模板办法 是运用,咱们直接运用就能够,并不需要知道内部的完结) 由于上下文现已封装好了整个bean的创立进程,内部完结对外是不敞开的,所以供给了 BeanPostProcessor(bean 创立 之前处理,bean 创立之后处理)、BeanFactoryPostProcessor (对beanDifinition 创立后处理)给 开发者 的扩展接口,在创立bean的进程中,添加自己的完结逻辑。

06 从迪迦(光、闪耀、火花)三种形态领悟的知识(实现Spring上下文,提供Bean创建的扩展)

完结

BeanPostProcessor Bean 创立完结前后扩展接口

它能够在 Bean 实例化、依赖注入、初始化前后等时刻对 Bean 进行一些额外的处理,例如修正 Bean 特点、动态署理等等。 这个类运用了模板办法形式。扩展类只需完结该接口,然后spring会在创立的bean的进程中调用这个办法完结 对bean的修正。 spring 在获取一切的 扩展类并完结扩展运用的是装修器形式,每个 扩展类都能够类比成一个装修器,然后通过职责链的办法完结调用。

**模板办法:**模板办法是一种行为规划形式,它界说了一个进程的骨架,并答应子类在不改变该进程结构的情况下从头界说某些步骤。 **装修器形式:**装修器形式是一种结构型规划形式,它答应动态地向目标添加新的行为,同时又不会改变其原有的行为。该形式通过一种装修器类来包装原有的类,然后给目标添加新的功能。 职责链形式:职责链形式是一种行为型规划形式,它将多个处理器(Handler)组成一条链,用于依次处理恳求,直到恳求被处理完结停止。在职责链形式中,每个处理器都有一个指向下一个处理器的引用,然后形成了一条处理链。

在实践开发进程中,咱们也能够测验运用这些规划形式来优化咱们的代码。在这个扩展接口的完结进程,咱们能够学到 模板 +装修器 +职责链的一种运用场景。很多时分,独自是规划形式并不能很好地解决问题,可是当咱们把他们组合到一起的时分,他就会变成一种很优雅的解决方案.


/**
 * @author huangle
 * @date 2023/2/13 15:18
 */
public interface BeanPostProcessor {
    /**
     * 在 Bean 目标履行初始化办法之前,履行此办法
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    /**
     * 在 Bean 目标履行初始化办法之后,履行此办法
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

BeanFactoryPostProcessor beanDefinition 加载完结后扩展接口

这个扩展规划跟上一个差不多,详细能够看上面的规划

public interface BeanFactoryPostProcessor {
    /**
     * 在一切的 BeanDefinition 加载完结后,实例化 Bean 目标之前,供给修正 BeanDefinition 特点的机制
     * @param beanFactory
     */
    void postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory);
}

AbstractApplicationContext 一致处理抽象类

AbstractApplicationContext完结对逻辑进程的整合,界说一致处理流程,完结进程通过界说抽象办法,交给详细的完结类去完结。 这儿其实就是对spring容器 初始化做一个 模板处理,只界说基本骨架,详细都交给后边的子类是完结。

public interface ConfigurableApplicationContext extends ApplicationContext{
    void refresh() throws BeansException;
}
/**
 * @author huangle
 * @date 2023/2/13 15:15
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
    /**
     * 模板办法,控制界说spring上下文的刷新与创立
     * @throws BeansException
     */
    @Override
    public void refresh() throws BeansException {
        // 1. 创立beanFactory,加载beanDefinition
        refreshBeanFactory();
        // 2. 获取 beanFactory
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 3. bean 实例化之前 履行 beanFactoryPostProcessor
        invokeBeanFactoryPostProcessors(beanFactory);
        // 4. beanPostProcessor 完结 bean 实例化后的注册操作
        registerBeanPostProcessors(beanFactory);
        // 5. 提早实例化 单例bean 目标
        beanFactory.preInstantiateSingletons();
    }
    protected abstract void refreshBeanFactory() throws BeansException;
    protected abstract ConfigurableListableBeanFactory getBeanFactory();
    /**
     * 初始化 BeanFactoryPostProcessor 处理器
     * @param beanFactory
     */
    private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory){
        Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
        for (BeanFactoryPostProcessor factoryPostProcessor : beanFactoryPostProcessorMap.values()) {
            // 处理 beanDifinition 扩展逻辑
            factoryPostProcessor.postProcessorBeanFactory(beanFactory);
        }
    }
    /**
     * 初始化 BeanPostProcessor 处理器
     * @param beanFactory
     */
    private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory){
        Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
        for (BeanPostProcessor postProcessor : beanPostProcessorMap.values()) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
}

AbstractAutowireCapableBeanFactory#createBean 一致处理bean扩展逻辑

spring流程的核心类,一切的扩展都会在这儿集合,一起作用于spring创立bean的进程。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
    private CglibSubclassingInstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
    @Override
    public Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) {
        Object bean = null;
        try {
            bean = createBeanInstance(beanDefinition, beanName, args);
            // 注入特点
            applyPropertyValues(beanName, bean, beanDefinition);
            // 供给给外部的扩展包装,履行 Bean 的初始化办法和 BeanPostProcessor 的前置和后置处理办法
            bean = initializeBean(beanName, bean, beanDefinition);
        } catch (Exception e) {
            throw new RuntimeException("bean create error!", e);
        }
        registerSingleton(beanName, bean);
        return bean;
    }
    private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) throws BeansException {
        // 1. 履行 BeanPostProcess before 操作
        Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        invokeInitMethods(beanName,wrappedBean,beanDefinition);
        // 2. 履行 BeanPostProcess after 操作
        wrappedBean = applyBeanPostProcessorsAfterInitialization(bean,beanName);
        return wrappedBean;
    }
    private void invokeInitMethods(String beanName, Object wrappedBean, BeanDefinition beanDefinition){
    }
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        // 职责链形式 去获取到用户的扩展内容,然后在这儿一致去处理
        for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
            Object current = beanPostProcessor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }
    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
       Object result = existingBean;
        for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
            Object current = beanPostProcessor.postProcessAfterInitialization(result, beanName);
            if (current == null){
                return result;
            }
            result = current;
        }
        return result;
    }
}

测验

界说 MyBeanFactoryPostProcessor、MyBeanPostProcecssor 扩展内容

/**
 * @author huangle
 * @date 2023/3/3 15:55
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        BeanDefinition userService = beanFactory.getBeanDefinition("userService");
        PropertyValues propertyValues = userService.getPropertyValues();
        PropertyValue propertyValue = new PropertyValue("nickname", "泰罗");
        propertyValues.addPropertyValue(propertyValue);
    }
}
/**
 * @author huangle
 * @date 2023/3/3 15:03
 */
public class MyBeanPostProcecssor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName)) {
            UserService userService = (UserService) bean;
            userService.setName("海绵宝宝");
        }
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

事务逻辑

public class UserDao {
    public String getUserName(){
        return "Anoxia";
    }
}
public class UserService {
    private String name;
    private String nickname;
    private UserDao userDao;
    public UserService(String name) {
        this.name = name;
    }
    public String say(){
        return userDao.getUserName()+" say hello "+name + "and" + nickname;
    }
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="userDao" class="cn.anoxia.springframework.beans.factory.support.UserDao"/>
    <bean id="userService" class="cn.anoxia.springframework.beans.factory.support.UserService">
        <property name="name" value="Anoxia"/>
        <property name="nickname" value="迪迦"/>
        <property name="userDao" ref="userDao"/>
    </bean>
    <bean id="myBeanPostProcecssor" class="cn.anoxia.springframework.beans.factory.support.MyBeanPostProcecssor"/>
    <bean id="myFactoryPostProcessor" class="cn.anoxia.springframework.beans.factory.support.MyBeanFactoryPostProcessor"/>
</beans>

测验类

testContext 测验 手动创立工厂、创立处理类,注入。testContext1测验自动读取xml文件,自动注入

@Test
    public void testContext() throws BeansException {
        // 1. 初始化bean工厂
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 2. 界说读取xml处理器,加载bean
        XmlBeanDefinitionReader definitionReader = new XmlBeanDefinitionReader(beanFactory);
        definitionReader.loadBeanDefinitions("classpath:spring.xml");
        // 3. BeanDefinition 加载完结 & Bean实例化之前,修正 BeanDefinition 的特点值
        MyBeanFactoryPostProcessor factoryPostProcessor = new MyBeanFactoryPostProcessor();
        factoryPostProcessor.postProcessorBeanFactory(beanFactory);
        // 4. Bean实例化之后,修正 Bean 特点信息
        MyBeanPostProcecssor postProcecssor = new MyBeanPostProcecssor();
        beanFactory.addBeanPostProcessor(postProcecssor);
        UserService userService = (UserService) beanFactory.getBean("userService");
        System.out.println(userService.say());
    }
    @Test
    public void testContext1() throws BeansException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        System.out.println(userService.say());
    }

测验成果

06 从迪迦(光、闪耀、火花)三种形态领悟的知识(实现Spring上下文,提供Bean创建的扩展)
06 从迪迦(光、闪耀、火花)三种形态领悟的知识(实现Spring上下文,提供Bean创建的扩展)

总结

这一节是学习spring进程中比较难的一节,如果学理解了这一节,对spring的扩展基本就理解了。学习的进程很枯燥,有很多时分,遇到一点问题就想抛弃,没有一追到底的意志。其实我感觉嗷,学起来累,学不理解,仍是自己会的东西太少了,导致上下连不起了,贯穿不了,导致寸步难行,继而抛弃。 怎么说呢,写代码这东西真的没有什么捷径,多写,多写,多写。只看不写,每一次有问题又是去copy,永远也不会。