Spring 框架中使用的设计模式
Java研发军团
共 9668字,需浏览 20分钟
· 2021-03-30
作者|icoding91
blog.csdn.net/caoxiaohong1005
1. 简单工厂(非23种设计模式中的一种)
实现方式:
读取bean的xml配置文件,将bean元素分别转换成一个BeanDefinition对象。 然后通过BeanDefinitionRegistry将这些bean注册到beanFactory中,保存在它的一个ConcurrentHashMap中。 将BeanDefinition注册到了beanFactory之后,在这里Spring为我们提供了一个扩展的切口,允许我们通过实现接口BeanFactoryPostProcessor 在此处来插入我们定义的代码。 典型的例子就是:PropertyPlaceholderConfigurer,我们一般在配置数据库的dataSource时使用到的占位符的值,就是它注入进去的。
各种的Aware接口 ,比如 BeanFactoryAware,对于实现了这些Aware接口的bean,在实例化bean时Spring会帮我们注入对应的BeanFactory的实例。 BeanPostProcessor接口 ,实现了BeanPostProcessor接口的bean,在实例化bean时Spring会帮我们调用接口中的方法。 InitializingBean接口 ,实现了InitializingBean接口的bean,在实例化bean时Spring会帮我们调用接口中的方法。 DisposableBean接口 ,实现了BeanPostProcessor接口的bean,在该bean死亡时Spring会帮我们调用接口中的方法。
设计意义:
public Object getSingleton(String beanName){
//参数true设置标识允许早期依赖
return getSingleton(beanName,true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//如果为空,则锁定全局变量并进行处理。
synchronized (this.singletonObjects) {
//如果此bean正在加载,则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//当某些方法需要提前初始化的时候则会调用addSingleFactory 方法将对应的ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用预先设定的getObject方法
singletonObject = singletonFactory.getObject();
//记录在缓存中,earlysingletonObjects和singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
getSingleton()过程图
5. 装饰器模式
实现方式:Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。
实质:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
6. 代理模式
实现方式:AOP底层,就是动态代理模式的实现。
动态代理:在内存中构建的,不需要手动编写代理类
静态代理:需要手工编写代理类,代理类引用被代理对象。
实现原理:切面在应用运行的时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象创建动态的创建一个代理对象。SpringAOP就是以这种方式织入切面的。
7. 观察者模式
实现方式:spring的事件驱动模型使用的是 观察者模式 ,Spring中Observer模式常用的地方是listener的实现。
具体实现:
事件机制的实现需要三个部分,事件源,事件,事件监听器
public abstract class ApplicationEvent extends EventObject {
private static final long serialVersionUID = 7099057708183571937L;
private final long timestamp;
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
public final long getTimestamp() {
return this.timestamp;
}
}
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
ApplicationContext接口[事件源]
职责:
public interface ApplicationEventPublisher {
void publishEvent(ApplicationEvent event);
}
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
private ApplicationEventMulticaster applicationEventMulticaster;
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
}
8. 策略模式
实现方式:
Resource 接口介绍
getInputStream():定位并打开资源,返回资源对应的输入流。每次调用都返回新的输入流。调用者必须负责关闭输入流。 exists():返回 Resource 所指向的资源是否存在。 isOpen():返回资源文件是否打开,如果资源文件不能多次读取,每次读取结束应该显式关闭,以防止资源泄漏。 getDescription():返回资源的描述信息,通常用于资源处理出错时输出该信息,通常是全限定文件名或实际 URL。 getFile:返回资源对应的 File 对象。 getURL:返回资源对应的 URL 对象。
UrlResource:访问网络资源的实现类。 ClassPathResource:访问类加载路径里资源的实现类。 FileSystemResource:访问文件系统里资源的实现类。 ServletContextResource:访问相对于 ServletContext 路径里的资源的实现类. InputStreamResource:访问输入流资源的实现类。 ByteArrayResource:访问字节数组资源的实现类。
9. 模版方法模式
经典模板方法定义:
抽象方法:父类中的是抽象方法,子类必须覆盖 钩子方法:父类中是一个空方法,子类继承了默认也是空的
Spring 模板方法模式实质:
具体实现:
public abstract class JdbcTemplate {
public final Object execute(String sql){
Connection con=null;
Statement stmt=null;
try{
con=getConnection();
stmt=con.createStatement();
Object retValue=executeWithStatement(stmt,sql);
return retValue;
}catch(SQLException e){
...
}finally{
closeStatement(stmt);
releaseConnection(con);
}
}
protected abstract Object executeWithStatement(Statement stmt, String sql);
}
引入回调原因:
public interface StatementCallback{
Object doWithStatement(Statement stmt);
public class JdbcTemplate {
public final Object execute(StatementCallback callback){
Connection con=null;
Statement stmt=null;
try{
con=getConnection();
stmt=con.createStatement();
Object retValue=callback.doWithStatement(stmt);
return retValue;
}catch(SQLException e){
...
}finally{
closeStatement(stmt);
releaseConnection(con);
}
}
...//其它方法定义
}
JdbcTemplate jdbcTemplate=...;
final String sql=...;
StatementCallback callback=new StatementCallback(){
public Object=doWithStatement(Statement stmt){
return ...;
}
}
jdbcTemplate.execute(callback);
END
顺便给大家推荐一个GitHub项目,这个 GitHub 整理了上千本常用技术PDF,绝大部分核心的技术书籍都可以在这里找到,
GitHub地址:https://github.com/javadevbooks/books
Gitee地址:https://gitee.com/javadevbooks/books
电子书已经更新好了,你们需要的可以自行下载了,记得点一个star,持续更新中..
评论
如何画出漂亮的神经网络图?神经网络可视化工具集锦搜集
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达1. draw_convnet一个用于画卷积神经网络的Python脚本https://github.com/gwding/draw_convnet2. NNSVGhttp://alexlenail.me/NN-SVG/LeNet.
小白学视觉
0
三个优秀的PyTorch实现语义分割框架
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达转自 | 机器学习AI算法工程使用的VOC数据集链接开放在文章中,预训练模型已上传Github,环境我使用Colab pro,大家下载模型做预测即可。代码链接: https://github.com/lixiang007
小白学视觉
0
使用 YOLO 进行自定义对象检测
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达我们知道我们可以专门检测一些对象。那么我们如何训练系统检测自定义对象呢?让我们一步一步来。1. 创建数据集机器是通过数据集学习的。数据集必须包含图像和标签。例如,让我的目标是创建一个检测坦克的系统。我准备了从网上下载的坦克图片。然
小白学视觉
0
如何看待稚晖君的时间管理水平?
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达计算机视觉life整理原文链接:https://www.zhihu.com/question/491456524/answer/2183081310稚晖君究竟是如何安排业余时间去做这么多高水平的项目?而且每个项目的用时也很少,普通
小白学视觉
2
如何确定神经网络的层数和隐藏层神经元数量?
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达公众号:尤而小屋作者:呦呦鹿鸣编辑:Peter大家好,我是Peter~关于神经网络中隐藏层的层数和神经元个数充满了疑惑。刚好看到一篇文章很好地答疑了,分享给大家~https://zhuanlan.zhihu.com/p/10041
小白学视觉
0
“海优最初弄出来可并不是为了给大佬弟子开后门的, 学术界现在几乎不存在任何套利空间,不要相信有什么办法可以投机取巧”
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达知乎问题:为什么部分同学倾向土博+国外博后而不是直接国外读博?感觉身边土博越来越多,基本都是土博➕海博后,申国外phd的明显减少(相比较疫情之前几年)知乎Tianteman: 这个问题下,可以看得出一部分国内硕博信息检索能力差的离
小白学视觉
0
神经网络之CNN与RNN的关系
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达1、CNN介绍CNN是一种利用卷积计算的神经网络。它可以通过卷积计算将原像素很大的图片保留主要特征变成很小的像素图片。本文以李宏毅老师ppt内容展开具体介绍。1.1 Why CNN for Image①为什么引入CNN ?图片示意
小白学视觉
0
真高!比亚迪员工爆料比亚迪在越南的薪资水平:基本工资480万,全勤奖35万,交通补助20万,餐补110万,每周6天,每天10小时
上一篇:某大公司为逼迫员工离职,竟然把他的工位安排到厕所旁,没想到他直接开始记录领导的如厕时间,还发到公司大群...对此,你怎么看?--完--PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。全文完,感谢你的耐心阅读。如果你还想看到我的文章,请一定给本
开发者全社区
0