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 )
0 commit comments