栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

Tiny-Spring——ApplicationContext系列

Java 更新时间:发布时间: 百科书网 趣学号

详情请见 https://github.com/StrongChenYu/Tiny-Spring

1. 为什么要有ApplicationContext

ApplicationContext主要是为了将以下几个步骤(当然源spring中可能有更多)整合起来,放到一个容器中,提供生命周期管理。

  1. 读xml文件,进行bean的读取和beanDefinition的读取
  2. 注册postProcessor
  3. 注册BeanFactoryPostProcessor
  4. invoke BeanFactoryPostProcessor

如果不经过ApplicationContext,那么这一系列的过程大概是这样的,需要自己手动去注册路径,注册postprocessor等一系列的操作。

@Test
public void testBeanFactoryPostProcessorAndBeanPostProcessor() {
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
    reader.loadBeanDefinition("classpath:spring.xml");

    BeanFactoryPostProcessor myBeanFactoryPostProcessor = (BeanFactoryPostProcessor) factory.getBean("myBeanFactoryPostProcessor");
    myBeanFactoryPostProcessor.postProcessBeanFactory(factory);

    factory.addBeanPostProcessor((BeanPostProcessor) factory.getBean("myBeanPostProcessor"));

    UserService userService = factory.getBean("userService", UserService.class);

    System.out.println(userService);

}

而有了ApplicationContext后,这一系列的操作都被整合到ApplicationContext的refresh方法中了。

@Test
public void testXML() {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
    applicationContext.registerShutdownHook();

    UserService userService = applicationContext.getBean("userService", UserService.class);
    System.out.println("测试结果:" + userService);
}

2. ApplicationContext的结构

大概这个样子

继承:ApplicationContext的一系列继承
组合:组合DefaultListableBeanFactory,主要用于委托接口中的功能。

3. ApplicationContext中需要实现的各个部分

整体就是refresh中的九个步骤

public void refresh() throws BeansException {
    // 1. 加载BeanDefinition
    refreshBeanFactory();
    // 2. 获取beanFactory
    ConfigurableListableBeanFactory factory = getBeanFactory();
    // 3. 添加ApplicationContextAwareProcessor
    factory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    // 4. 调用factoryPostProcessor
    invokeBeanFactoryPostProcessor(factory);
    // 5. 注册beanPostProcessor
    registerBeanPostProcessor(factory);
    // 6. 初始化事件
    initApplicationEventMulticaster();
    // 7. 注册listener
    registerListener();
    // 8. 这里会把所有的bean全部调用一次getBean方法
    factory.preInstantiateSingletons();
    // 9. finish
    finishRefresh();
}

一些具体的实现

3.1 FactoryBean

**FactoryBean**和**BeanFactory**的区别
BeanFactory是用来生成Bean和管理Bean的
而FactoryBean也属于Bean
如果容器getBean时发现是一个FactoryBean,就会去调用FactoryBean的getObject方法。
这样做有什么用途呢?
一个实际的案例就是Mybatis中,利用FactoryBean为service层的对象自动提供代理
在调用service的createBean时,去get具体的ORM对象时,会调用他的getObject方法。

3.2 ResourceLoader

和XmlBeanDefinitionReader组合,从xml中解析bean对象
XmlBeanDefinitionReader和ResourceLoader组合,加载流并且获取流
ResourceLoader的类结构

![6f9066b0befd2560ecb35b6deb60b47.jpg](https://img-blog.csdnimg.cn/img_convert/c19df4d6ac10e41d99170a265260f395.png#clientId=ubefb3246-44b9-4&from=drop&height=270&id=u7dfbe160&margin=[object Object]&name=6f9066b0befd2560ecb35b6deb60b47.jpg&originHeight=1080&originWidth=1440&originalType=binary&ratio=1&size=61846&status=done&style=none&taskId=uf750b49c-c8e9-43cd-a459-c3f1b9c184a&width=360)

3.3 Event and listener

这部分通过定义了一个ApplicationContextMulticaster对象用来管理和通知listener
如果有event发生
通过application.publishEvent方式
那么就会通过ApplicationContextMulticaster对象通知所有的listener,listener检查是不是自己的event
主要通过检查泛型类是否和event一样
然后调用listener的响应的方法。

3.4 Aware

Aware的作用是给bean提供了一个可以反向利用Spring framework中组件的机会,他会在getBean中的createBean方法中判断bean需要哪一个类型的aware,然后调用相应的set方法,将容器中的组件set进去,大概像是这个样子(反射)

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationStartupAware) {
        ((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}
4. 总结 4.1 设计模式
  • 经典的模板方法模式。(严格意义上来说不算是模板方法模式,只是把各个功能分层,不同的实现放到了不同的抽象类中。
  • 委托模式。ApplicationContext也继承自BeanFactory,但他的关于这部分的方法实现委托给了同样实现了该相关接口的DefaultListableBeanFactory。但是ApplicationContext实现ListableBeanFactory二层子接口,但是DefaultListableBeanFactory实现了三个二层子接口,为什么还能委托? 我感觉到就是这种模式的精妙之处,只把自己需要的部分委托出去。(有深意,注意理解)。
  • 适配器模式。DisposableBeanAdapter(这个的作用是,将disposableBean和destoryMethod中的统一到一个adpater中,然后容器统一去处理这个adpater
  • 观察者模式。事件处理(使用经典的观察者模式)multicaster相当于subject,listener相当于订阅者,至于两者的绑定是在容器中的refresh中进行的。(get所有type为applicationListener的bean,然后绑定)
4.2 接口的继承

慢慢体会到,接口这样分层的目的,可以起到控制权限的作用。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/273626.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号