栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式 笔记7 | 抽象工厂模式 在源码中的应用 Spring篇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式 笔记7 | 抽象工厂模式 在源码中的应用 Spring篇

文章目录
  • 一、Spring 概述
  • 二、Spring 中的抽象工厂模式
  • 三、总结

一、Spring 概述

参考资料:https://baike.baidu.com/item/spring/85061?fr=aladdin
Spring 是 JavaEE 编程领域的一个轻量级开源框架,由Rod Johnson 先生在2002年最早提出并随后创建。

Spring 是一个开源容器框架,集成各类型的工具,通过核心的 Bean Factory 实现了底层的类的实例化和生命周期的管理。

Spring 的主要特点:

  • IoC(Inverse of Control 控制反转),实现低耦合,底层采用工厂设计模式,所有的 Bean 都需注册到 Bean 工厂中,将 Bean 的初始化和生命周期的监控都交给工厂进行管理
  • AOP (Aspect Oriented Programming) 面向切面编程
  • DI (Dependency Injection) 依赖注入,可以注入普通类型或者对象到 Spring 容器中
二、Spring 中的抽象工厂模式

运行环境:

  • SpringBoot v2.6.9
  • Spring v5.3.21

由于 Spring 的几大特点: IoC 、DI 和 AOP 得知,其底层使用 Bean 工厂来注册与管理 Bean,即 Java 的普通类型和对象,那么我们可以来了解一下其底层的 Bean 工厂:

org.springframework.beans.factory.BeanFactory

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

public interface BeanFactory {

    // Bean 自带的前缀
	String FACTORY_BEAN_PREFIX = "&";
    // 1. 根据名称获取 Bean
	Object getBean(String name) throws BeansException;
    // 2. 根据名称获取 Bean, 并转化为指定的对象
	 T getBean(String name, Class requiredType) throws BeansException;
    // 3. 根据名称获取 Bean, 并传入构造该Bean的参数,用于有参构造
	Object getBean(String name, Object... args) throws BeansException;
    // 4. 根据字节码获取 Bean
	 T getBean(Class requiredType) throws BeansException;
    // 5. 根据字节码获取 Bean,并传入构造该Bean的参数,用于有参构造
	 T getBean(Class requiredType, Object... args) throws BeansException;
    // 6. 根据字节码获取指定 Bean 的提供者
	 ObjectProvider getBeanProvider(Class requiredType);
    // 7. 根据指定的解析类型获取 Bean 的提供者
	 ObjectProvider getBeanProvider(ResolvableType requiredType);
    // 8. 判断工厂是否包含 Bean
	boolean containsBean(String name);
    // 9. 根据名称判断 Bean 是否为单例的对象
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    // 10. 根据名称判断 Bean 是否为原型对象
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    // 11. 根据名称判断 Bean 是否能被指定的可解析类型解析
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    // 12. 根据名称判断 Bean 是否被指定的字节码对应的类进行解析
	boolean isTypeMatch(String name, Class typeToMatch) throws NoSuchBeanDefinitionException;
    // 13. 根据名称获取 Bean 的类型对应的字节码
	@Nullable
	Class getType(String name) throws NoSuchBeanDefinitionException;
    // 14. 根据名称获取 Bean 的类型对应的字节码,并设置是否允许Bean初始化
	@Nullable
	Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
    // 15. 获取 Bean的别名
	String[] getAliases(String name);
}

根据对 BeanFactory 接口的方法的作用进行概括,可发现其中所有都是关于 Bean 的操作,要么通过 name、类型的字节码去获取 Bean ,要么就是根据名称或者 ResolvableType 来判断 Bean 是 singleton 单例的 还是 prototype 原型的,但是这里面没有关于 Bean 注入的内容,原因是 Spring 底层提供了 Bean 注册中心,而 BeanFactory接口主要只是声明获取 Bean 信息的相关方法。

接下来我们观察 BeanFactory 接口的实现类有哪些:

在 Spring 5.3.21 版本中,BeanFactory 的工厂实现类多达50个,这里我们不一一的去查看,通常其实现的非抽象类都会继承于指定的抽象类,然后又实现该抽象类的接口,这是一种结构型的设计模式。(具体是什么我忘记了)。

所以我们可以先看其抽象实现类,目前 BeanFactory 的抽象实现类就图中的七个

首先关注 AbstractApplicationContext 这个抽象类,因为当我们在获取 Spring中的 Bean时,可以通过工厂也可以通过应用上下文

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
}

比如在传统的 Spring 开发中获取Bean,通过 Spring 的应用上下文获取。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean(User.class);

这里是通过 Spring 配置文件来创建 ClassPathXmlApplicationContext 对象

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
}

单从其父类来看,ClassPathXmlApplicationContext 似乎并不是抽象类 AbstractApplicationContext 的子类,但是从它的类名里可以看出,都带着 ApplicationContext后缀,必然是实现了同一个接口,这里我使用 IDEA 工具对类的关系进行可视化可以得出下图,ClassPathXMLApplicationContext 是 AbstractApplicationContext 的间接子类

在 Spring 底层,BeanFactory 接口的子类除了 ClassPathXmlApplicationContext,还有 XmlWebApplicationContext、StaticWebApplicationContext、StaticApplicationContext,如下图

而这些类直接不一定是直接继承的关系,也有可能是间接继承,即中间还有其他的抽象类,它们都实现了 ApplicationContext 这个接口

在 Spring 底层,org.springframework.beans.factory.support.DefaultListableBeanFactory 实现了所有工厂的逻辑

三、总结

Spring 中 BeanFactory 接口声明了关于获取 Bean信息的方法,其他所有的工厂都是 BeanFactory 的子类,虽然在 BeanFactory 里没有显式地声明具体有哪些工厂,但是那些工厂都需要实现这个接口,这也是一种抽象工厂模式的设计方法,BeanFactory相当于抽象工厂,而其继承子类就相当于产品,不同的工厂类就相当于不同的产品。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1029074.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号