Java设计模式结合Spring源码案例(一)|策略模式+工厂模式
前言
年初前几个月全刷了一遍Head First系列的设计模式(学渣表示三个月才看完一本书😂😂),当时自己看完对于系统架构设计以及代码层设计都有了非常深刻的认识和理解。Head First系列书特色是采用引导式教学,不直接告诉你怎么做,而是利用故事带领读者思考并解决问题(经历过教科式的十六年教育,刚看这本书风格还真不习惯🤣🤣)看完本书后一直想写博客总结下现有的主要设计模式以及各设计模式代码案例,前面由于忙于迁移更新博客花费了了较多时间,从这篇文章开始讲会总结每本书看完后的自己的知识总结和认识理解,如有不当,敬请指正,谢谢!
我的github主页地址 https://xdj68.github.io
一、设计模式简介
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。
二、设计模式原则
Java是面向对象的编程语言,其中包括四种OO基本概念:抽象,封装,继承,多态。设计原则同样面向对象设计,其中包含九大OO基本原则:
- 封装变化
- 多用组合,少用继承
- 针对接口编程,不针对实现编程
- 为交互对象之间的松耦合设计而努力
- 开闭原则(Open Close Principle)—类应该对扩展开放,对修改关闭
- 依赖倒置原则(Dependency Inversion Principle)—依赖抽象,不要依赖具体类
- 最少知识原则(Least Knowledge Principle)—只和朋友交谈
- 好莱坞原则(Hollywood Principle)—别找我,我会找你
- 单一责任原则(Single Responsibility Principle)—类应该只有一个改变的理由
三、设计模式类型
设计模式主要包括23种类型,这些模式可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns),我们还会讨论业务类型的设计模式:J2EE 设计模式。
命令 | 描述 |
---|---|
创建型模式 |
|
结构型模式 |
|
行为型模式 |
|
J2EE 模式 |
|
四、设计模式之策略模式
4.1 .策略模式简介
定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
五、设计模式之工厂模式
5.1 工厂模式简介
工厂模式主要分为俩种:抽象工厂和工厂方法。
PS:简单工厂就是封装严格来说属于策略模式。
5.2. 抽象工厂简介
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类
5.3. 工厂方法简介
定义了一个创建对象的接口,但由子类决定需要实例化哪一个类。工厂方法把类的实例化延迟到子类执行
5.4. Spring案例: BeanFactory简介
首先介绍下下Spring Bean的生命周期:
5.4.1 Spring Bean 的生命周期简介
Spring Bean 需要在容器启动时根据 Java 或 XML Bean 定义进行实例化。框架可能还需要执行一些初始化前和初始化后的步骤以使 Bean 进入可用状态,当不再需要 Bean 时会将其从 IoC容器中移除。同时与初始化阶段一样,Spring 框架可能需要执行销毁前和销毁后的步骤以释放其他系统资源。Spring Bean工厂负责管理在 Spring 容器中创建的 Bean 的生命周期回调。
5.4.2 Spring Bean 的生命周期过程
- 1 加载Bean 定义规范
- 2 依赖注入 a.实例化Beans b.调用setter进行属性赋值
- 3 BPP创建初始/销毁Beans
5.4.3 Spring Bean 的生命周期回调
Spring Bean工厂负责管理在 Spring 容器中创建的 Bean 的生命周期回调,主要可以归类为俩大类:
Post-initialization 后-初始回调方法
Pre-destruction 前-销毁回调方法
实现Bean生命周期的回调主要存在以下四种方式:
- a. 实现回调InitializingBean接口-重写afterPropertiesSet() 方法 实现回调DisposableBean接口-重写destroy()方法
- b. 实现回调Aware接口-例如:BeanNameAware 创建该Bean工厂中指定名字
- c. XML配置Bean属性 init-method destroy-method
- d. 新增注解@PostConstruct @PreDestroy
建议采用XML配置Bean属性和注解方式可以更加灵活进行变更配置
5.4.4 BeanFactory 整体类结构UML简介
Spring IoC 容器是 Spring Framework 的核心。容器将创建对象,将它们连接在一起,配置它们,并管理它们从创建到销毁的完整生命周期。Spring 容器使用依赖注入 (DI) 来管理组成应用程序的组件。 Spring 提供了以下两种类型的容器:
BeanFactory 容器
应用上下文容器
5.4.5 BeanFactory 中的 抽象工厂 设计模式应用
- DefaultListableBeanFactory 是Bean工厂的一个默认实现
- StaticListableBeanFactory是简化版的DefaultListableBeanFactory由于未实现BeanDefinitionRegistry,所以不支持BeanDefinition的注册操作
- BeanFactory提供一个接口,用于创建相关工厂的家族
- DefaultListableBeanFactory和StaticListableBeanFactory是具体实现类,属于抽象工厂设计模式,目的就是集中管理SpringBean的实例化、定位、配置及依赖
5.4.6 BeanFactory 中的 工厂方法 设计模式应用
- AbstractBeanFactory 是的BeanFactory的抽象基类,目的是获取Bean规范定义
- AbstractAutowireCapableBeanFactory是实现默认Bean创建的抽象工厂超类
- AbstractBeanFactory定义了一个创建对象的接口,抽象方法createBean是为了合并Bean规范定义创建Bean实例,所有的Bean检索方法都委托此方法进行实际的Bean创建
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException;
}
AbstractAutowireCapableBeanFactory是AbstractBeanFactory 的子类,由子类决定实例化Bean,属性赋值,应用BPP等操作。工厂方法把类的实例化延迟到子类执行,属于工厂方法的设计模式,目的是由子类控制创建Bean实例过程。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
AbstractBeanFactory 定义了一个创建对象的接口,抽象方getBeanDefinition是为了BeanFactory返回给定名字的Bean规范定义
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
DefaultListableBeanFactory是AbstractBeanFactory 的子类,由子类决定返回给定名字的Bean规范定义。工厂方法把类的实例化延迟到子类执行,属于工厂方法的设计模式,目的是由子类控制给定名字的Bean规范定义过程。
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (logger.isTraceEnabled()) {
logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
总结
好的开始是成功的一半,终于写完了策略模式(封装不多讲)和工厂模式在Spring Bean生命周期中的简单应用。下篇继续研究下Spring源码做其他设计模式的分析,由于此系列是讲设计模式,Spring源码分析略带而过,后期准备写完整的Spring源码分析篇(希望能写到Spring源码初步掌握那天😄😄,给吊车尾的自己加加油,未来的路还很长💪💪!)
工作搬砖简单坚持写博客难,希望能够坚持有时间写一写文章,积累下遇到的问题和解决方式以及知识点总结!!
我的github主页地址 https://xdj68.github.io
参考文档:
https://howtodoinjava.com/spring-core/spring-bean-life-cycle https://www.zhihu.com/question/38597960
Head of First 设计模式