Skip to content

Commit cd7ca80

Browse files
committed
📝spring
1 parent cc4f9b5 commit cd7ca80

File tree

8 files changed

+606
-8
lines changed

8 files changed

+606
-8
lines changed

docs/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
>
2020
> 不忘初心是对的,但要切记要出发
2121
22-
22+
![](https://cdn.jsdelivr.net/gh/Jstarfish/picBed/img/20200907141047.png)
2323

2424
### ToDoList
2525

@@ -28,4 +28,5 @@
2828

2929
> 作为一个深耕在互联网公司的 Java 码农,在准备换坑的时候,才发现这么些年都没有一个对所学知识的整理,所以就整理下之前的笔记和一些正在学习的内容。
3030
31-
![](https://imgkr.cn-bj.ufileos.com/6e7c80a9-48e6-4a2a-b920-682d8f0bab5c.png)
31+
> 文章持续更新,可以微信搜「 **JavaKeeper** 」第一时间阅读,无套路领取 500+ 本电子书和 30+ 视频教学和源码,本文 **GitHub** [github.com/JavaKeeper](https://github.com/Jstarfish/JavaKeeper) 已经收录,Javaer 开发、面试必备技能兵器谱,有你想要的。
32+

docs/_images/redis/redis-watch.png

60 KB
Loading

docs/data-store/Redis/Redis-Transaction.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
> 文章收录在 GitHub [JavaKeeper](https://github.com/Jstarfish/JavaKeeper) ,N线互联网开发必备技能兵器谱
2+
13
![](https://cdn.jsdelivr.net/gh/Jstarfish/picBed/img/20200824161651.jpg)
24

35
> 假设现在有这样一个业务,用户获取的某些数据来自第三方接口信息,为避免频繁请求第三方接口,我们往往会加一层缓存,缓存肯定要有时效性,假设我们要存储的结构是 hash(没有String的'**SET anotherkey "will expire in a minute" EX 60**'这种原子操作),我们既要批量去放入缓存,又要保证每个 key 都加上过期时间(以防 key 永不过期),这时候事务操作是个比较好的选择
@@ -279,4 +281,10 @@ void touchWatchedKey(redisDb *db, robj *key) {
279281
280282
**最后**
281283
282-
Redis 事务在发送每个指令到事务缓存队列时都要经过一次网络读写,当一个事务内部的指令较多时,需要的网络 IO 时间也会线性增长。所以通常 Redis 的客户端在执行事务时都会结合 pipeline 一起使用,这样可以将多次 IO 操作压缩为单次 IO 操作。
284+
Redis 事务在发送每个指令到事务缓存队列时都要经过一次网络读写,当一个事务内部的指令较多时,需要的网络 IO 时间也会线性增长。所以通常 Redis 的客户端在执行事务时都会结合 pipeline 一起使用,这样可以将多次 IO 操作压缩为单次 IO 操作。
285+
286+
287+
288+
### 参考资料
289+
290+
[1] Redis设计与实现: *https://redisbook.readthedocs.io/en/latest/feature/transaction.html#id3*

docs/data-structure/Recursion.md

Lines changed: 527 additions & 1 deletion
Large diffs are not rendered by default.

docs/design-pattern/Template-Pattern.md

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
> 模板方法模式
1+
> 模板方法模式——看看 JDK 和 Spring 是如何优雅复用代码的
22
>
33
> 文章收录在 GitHub [JavaKeeper](https://github.com/Jstarfish/JavaKeeper) ,N线互联网开发必备技能兵器谱
44
@@ -263,9 +263,69 @@ public static void main(String[] args) {
263263

264264
这个模式的重点在于提供了一个固定算法框架,并让子类实现某些步骤,虽然使用继承是标准的实现方式,但通过回调来实现,也不能说这就不是模板方法。
265265

266+
其实并发编程中最常见,也是面试必问的 AQS 就是一个典型的模板方法。
267+
268+
269+
266270
### Spring 中的模板方法
267271

268-
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gihaulhakyj30yc0qokcz.jpg)
272+
Spring 中的设计模式太多了,而且大部分扩展功能都可以看到模板方式模式的影子。
273+
274+
我们看下 IOC 容器初始化时中的模板方法,不管是 XML 还是注解的方式,对于核心容器启动流程都是一致的。
275+
276+
`AbstractApplicationContext``refresh` 方法实现了 IOC 容器启动的主要逻辑。
277+
278+
一个 `refresh()` 方法包含了好多其他步骤方法,像不像我们说的 **模板方法**`getBeanFactory()``refreshBeanFactory()` 是子类必须实现的抽象方法,`postProcessBeanFactory()` 是钩子方法。
279+
280+
```java
281+
public abstract class AbstractApplicationContext extends DefaultResourceLoader
282+
implements ConfigurableApplicationContext {
283+
@Override
284+
public void refresh() throws BeansException, IllegalStateException {
285+
synchronized (this.startupShutdownMonitor) {
286+
prepareRefresh();
287+
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
288+
prepareBeanFactory(beanFactory);
289+
postProcessBeanFactory(beanFactory);
290+
invokeBeanFactoryPostProcessors(beanFactory);
291+
registerBeanPostProcessors(beanFactory);
292+
initMessageSource();
293+
initApplicationEventMulticaster();
294+
onRefresh();
295+
registerListeners();
296+
finishBeanFactoryInitialization(beanFactory);
297+
finishRefresh();
298+
}
299+
}
300+
// 两个抽象方法
301+
@Override
302+
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
303+
304+
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
305+
306+
//钩子方法
307+
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
308+
}
309+
}
310+
```
311+
312+
打开你的 IDEA,我们会发现常用的 `ClassPathXmlApplicationContext``AnnotationConfigApplicationContext` 启动入口,都是它的实现类(子类的子类的子类的...)。
313+
314+
`AbstractApplicationContext`的一个子类 `AbstractRefreshableWebApplicationContext` 中有钩子方法 `onRefresh() `的实现:
315+
316+
```java
317+
public abstract class AbstractRefreshableWebApplicationContext extends …… {
318+
/**
319+
* Initialize the theme capability.
320+
*/
321+
@Override
322+
protected void onRefresh() {
323+
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
324+
}
325+
}
326+
```
327+
328+
看下大概的类图:
269329

270330
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gihav1jqqjj30vc0eotgf.jpg)
271331

@@ -283,8 +343,10 @@ public static void main(String[] args) {
283343

284344

285345

286-
参考:
346+
## 参考:
287347

288348
《Head First 设计模式》、《研磨设计模式》
289349

290-
https://sourcemaking.com/design_patterns/template_method
350+
https://sourcemaking.com/design_patterns/template_method
351+
352+
![](https://cdn.jsdelivr.net/gh/Jstarfish/picBed/img/20200907141047.png)

docs/java/JUC/readJUC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
- [CountDownLatch、CyclicBarrier、Semaphore](java/JUC/CountDownLatch、CyclicBarrier、Semaphore.md)
1515
- [AQS](java/JUC/AQS.md)
1616

17+
![J.U.C 类分类](https://img-blog.csdn.net/20170126201206425?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDg1MzI2MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

images/1.png

-137 KB
Binary file not shown.

images/article_end.png

-1000 KB
Binary file not shown.

0 commit comments

Comments
 (0)