Spring中事件广播原理
SpringFramework 的事件模型
- ApplicationEventPublisher:事件发布器,是用来接受事件,并交给事件广播器处理
- ApplicationEventMulticaster:事件广播器,拿到事件发布器的事件,并广播给监听器
ApplicationContext 接口继承了 ApplicationEventPublisher ,拥有事件发布的功能;ApplicationContext 的第一个抽象实现类 AbstractApplicationContext 组合了一个 ApplicationEventMulticaster ,拥有事件广播的能力。综合来看,ApplicationContext 的落地实现就已经能够完成事件驱动模型中的 “观察者” 身份了
Spring中SPI的使用
Spring中模块装配的三种方式
@Import
可直接导入普通类、配置类、ImportSeletor 的实现类和 ImportBeanDefinitionRegistrar 的实现类,通常情况下是写在自定义注解上
编写 ImportSeletor 的实现类
1 | public interface ImportSelector { |
通过 selectImports 方法导入对象,返回的是一组需要导入的类的全限定类名
Spring中三种后置处理器对比
BeanPostProcessor | BeanFactoryPostProcessor | BeanDefinitionRegistryPostProcessor | |
---|---|---|---|
处理目标 | bean 实例 | BeanDefinition | BeanDefinition、.class 文件等 |
执行时机 | bena 的初始化阶段前后(已创建出 bean 对象) | BeanDefinition解析完毕并注册进 BeanFactory 之后(此时 bean 未实例化) | 配置文件、配置类已解析完毕并注册进 BeanFactory,但还未被 BeanFactoryPostProcessor 处理 |
可操作空间 | 对 bean 的属性赋值、创建代理对象等 | 给 BeanDefinition 中增删属性,移除 BeanDefinition 等 | 向 BeanFactory 中注册新的 BeanDefinition 和 BeanFactoryPostProcessor |
Spring中控制Bean生命周期的三种方式
@PostConstruct & @PreDestroy | InitializingBean & DisposableBean | init-method & destory-method | |
---|---|---|---|
执行顺序 | 最先 | 中间 | 最后 |
组件耦合度 | 与 JSR 规范耦合 | 与 SpringFramework 耦合 | 无侵入(只有 <bean> 和 @Bean 中使用) |
容器支持 | 注解原生支持,xml需开启注解驱动 | xml 、注解原生支持 | xml 、注解原生支持 |
单实例Bean | ✔ | ✔ | ✔ |
原型Bean | ✔ | ✔ | 只支持 init-method |
网络IO-探究poll和epoll在内核层面的不同
代码、资料来自于马士兵MAC课程。
本文通过 strace 命令来监控使用 poll 和 epoll 不同模型的同一代码在内核方法调用上的不同。
阅读本文,你将切实体会到 poll 和 epoll 的不同实现方式。对于两种模型的介绍推荐阅读:网络IO-IO模型的演变。
前置:如何用同一段代码使用 poll 和 epoll 两种不同模型
代码 Selector selector = Selector.open(); 在 poll 和 epoll 模型都支持的情况下优先选择 epoll。
可以通过 JVM 参数 -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.PollSelectorProvider 手动选择 poll 模型。
网络IO-IO模型的演变
代码、资料来自于马士兵MAC课程。
本文主要讲解了IO模型,由 BIO 到 NIO,再演变到多路复用 select/poll 和 epoll 的过程。
从本文中你可以了解到不同模型是如何解决之前模型所产生的问题,并且会带来什么样的新问题。
算法题-实现LRU缓存机制
题目
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:
- LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
- int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
- void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
示例:
1 | 输入 |
网络IO-tcp是怎么建立通信的
学习马士兵课程-内存与IO,通过 netstat、lsof、tcpdump 观察tcp连接时内核在每一步都就行了什么相应的操作。
本文资料来自于马士兵MAC课程-内存与IO。
通过 netstat、lsof、tcpdump 观察 tcp 连接时内核在每一步都就行了什么相应的操作。
阅读本文,你可以知道在编写 java 代码时的每一步对应内核会产生哪些操作,其探究范围在客户端、服务端代码启动到客户端、服务端建立连接。