系列文章目录
文章目录
- 系列文章目录
- 一、单例模式
- 二、工厂模式
- 三、代理模式
-
- [3.1 Spring AOP 中的动态代理](#3.1 Spring AOP 中的动态代理)
- [3.2 MyBatis中的Mapper代理](#3.2 MyBatis中的Mapper代理)
- 四、适配器模式
- 五、责任链模式
-
- [5.1、Spring Cloud Gateway 中的 Filter](#5.1、Spring Cloud Gateway 中的 Filter)
- 六、享元模式
-
- [6.1 java集合框架](#6.1 java集合框架)
- 七、桥接模式
-
- [7.1 JDBC驱动](#7.1 JDBC驱动)
- 八、装饰器模式
-
- [8.1 JAVA IO 流](#8.1 JAVA IO 流)
- 九、模板模式
-
- [9.1 Spring JdbcTemplate](#9.1 Spring JdbcTemplate)
一、单例模式
核心思想:保证一个类仅有一个实例,并提供全局访问点
框架应用:全局共享资源,比如spring中的单例bean
c
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
// 存储单例Bean的缓存(key:beanName,value:实例)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 获取单例Bean,核心逻辑:不存在则创建,存在则直接返回
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先从缓存查
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 加锁保证线程安全(双重检查锁)
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 若未创建,调用createBean创建实例并放入缓存
singletonObject = createBean(beanName); // 简化逻辑
this.singletonObjects.put(beanName, singletonObject);
}
}
}
return singletonObject;
}
}
spring通过concurrentHashmap缓存单例实例,结合sync保证线程安全,是懒汉式单例+DCL的实现
二、工厂模式
比如spring中的工厂模式,BeanFactory是spring的核心工厂接口,负责创建和管理Bean
c
// 工厂接口
public interface BeanFactory {
// 获取Bean(由子类实现创建逻辑)
Object getBean(String name) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
}
// 实现类:DefaultListableBeanFactory(Spring 最核心的Bean工厂)
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory {
// 存储Bean定义(创建Bean的元数据)
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
@Override
public Object getBean(String name) throws BeansException {
// 根据Bean定义创建实例(简化逻辑)
BeanDefinition bd = beanDefinitionMap.get(name);
return createBean(bd); // 封装了复杂的创建逻辑(如依赖注入、初始化)
}
}
用的时候,只需要通过getBean("xxx")获取对象,不需要关心Bean的创建依赖注入等细节,由工厂统一处理
三、代理模式
核心思想:通过代理对象控制原对象的访问,可以在原逻辑前后添加额外操作(日志,事务)
3.1 Spring AOP 中的动态代理
spring AOP基于JDK动态代理或者CGLIB代理实现,例如事务管理
c
// JDK动态代理示例(Spring 内部逻辑简化)
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
private final AdvisedSupport advised;
public JdkDynamicAopProxy(AdvisedSupport config) {
this.advised = config;
}
// 创建代理对象
@Override
public Object getProxy() {
return Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
advised.getTargetSource().getTargetClass(),
this // InvocationHandler,负责增强逻辑
);
}
// 代理对象的方法调用会触发这里
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 1. 执行前置增强(如事务开始)
List<Object> chain = advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 2. 执行目标方法(原对象的业务逻辑)
Object retVal = method.invoke(target, args);
// 3. 执行后置增强(如事务提交)
return retVal;
}
}
3.2 MyBatis中的Mapper代理
MyBatis 的 Mapper 接口没有实现类,通过代理生成实现
c
// Mapper代理工厂
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
// 创建代理对象
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface);
return (T) Proxy.newProxyInstance(
mapperInterface.getClassLoader(),
new Class[] { mapperInterface },
mapperProxy
);
}
}
// 代理逻辑
public class MapperProxy<T> implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 当调用Mapper接口的方法(如selectById),代理对象会执行SQL查询
return sqlSession.selectOne(method.getName(), args);
}
}
四、适配器模式
核心思想:将一个类的接口转换成客户端期望的另一个接口,解决接口不兼容问题
gateway过滤器里面的适配器模式

4.1.代码片段
这个实例gateway底层会把所有的过滤器整合到一起,所有的指的是普通过滤和全局过滤器
c
//普通过滤器实现GateWayFilter接口
List<GatewayFilter> gatewayFilters = route.getFilters();
//全局过滤器实现GlobalFilter接口
List<GatewayFilter> combined = new ArrayList(this.globalFilters);
//从下面可以看出,全局过滤器怎么来的,是通过调用loadFilters(globalFilters);
//GlobalFilter适配为GatewayFilter,适配是经过GatewayFilterAdapter ,所以这一行代码:
//List<GatewayFilter> combined = new ArrayList(this.globalFilters);
//最终也是成为普通过滤器
public class FilteringWebHandler implements WebHandler {
public FilteringWebHandler(List<GlobalFilter> globalFilters) {
this.globalFilters = loadFilters(globalFilters);
}
private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
return (List)filters.stream().map((filter) -> {
GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
if (filter instanceof Ordered) {
int order = ((Ordered)filter).getOrder();
return new OrderedGatewayFilter(gatewayFilter, order);
} else {
Order orderx = (Order)AnnotationUtils.findAnnotation(filter.getClass(), Order.class);
return (GatewayFilter)(orderx != null ? new OrderedGatewayFilter(gatewayFilter, orderx.value()) : gatewayFilter);
}
}).collect(Collectors.toList());
}
4.2、SpringMVC中的HandlerAdapter
spring mvc中,控制器有多种实现,@Controller\HttpRequestHandler, HandlerAdapter适配不同控制器接口,让DispatcherServlet统一调用
c
// 适配器接口
public interface HandlerAdapter {
// 判断是否支持该控制器
boolean supports(Object handler);
// 执行控制器逻辑
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
// 适配 @Controller 注解的控制器
public class RequestMappingHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof HandlerMethod; // 检查是否是@Controller的方法
}
@Override
public ModelAndView handle(...) {
// 调用@Controller中的@RequestMapping方法(适配逻辑)
return invokeHandlerMethod(request, response, (HandlerMethod) handler);
}
}
// 适配 HttpRequestHandler 接口的控制器
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
@Override
public ModelAndView handle(...) {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
}
五、责任链模式
责任链模式(Chain of Responsibility) 是一种行为型设计模式,它让多个对象有机会处理请求,从而避免请求的发送者与接收者之间的耦合。请求沿着链传递,直到有对象能够处理它为止。
5.1、Spring Cloud Gateway 中的 Filter

在 Spring Cloud Gateway 中,每个 Filter 都可以对请求或响应进行处理。它们被组织成一个过滤器链(Filter Chain),按照一定的顺序依次执行。
每个 Filter 调用 chain.filter(exchange) 来将请求传递给下一个 Filter。
这种结构类似于责任链:每个节点决定是否处理请求,或者将请求传递给下个节点。
c
public class MyFilter implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 做一些处理...
return chain.filter(exchange); // 把请求传给下一个 Filter
}
}
解耦请求的发起者和处理者: 请求(如 HTTP 请求)不需要知道具体的 Filter 是谁,只需要按顺序调用即可。
动态扩展性: 可以在运行时动态添加或移除 Filter,而无需修改原有代码。
灵活控制流程: 某些 Filter 可以提前终止请求(比如权限校验失败),而不必继续传递下去。
职责分离: 每个 Filter 只负责一个功能(如日志记录、限流、鉴权等)。
六、享元模式
核心思想是通过共享对象减少内存占用,适用于存在大量相似对象的场
6.1 java集合框架
Integer缓存: JDK对Integer类型实现了缓存池,默认范围是-128-127, 当使用Integer.valueof(n)或者自动装箱时,若数值在缓存范围内,会直接返回缓存中的对象而非新创建,避免重复创建相同的对象
c
Integer a = Integer.valueOf(100);
Integer b = Integer.valueOf(100);
System.out.println(a == b); // true(共享同一对象)
String 常量池:字符串字面量会被存储在常量池中,相同内容的字符串会共享同一个区域,减少内存消耗
七、桥接模式
核心思想:分离抽象与实现,使得两者可独立变化
7.1 JDBC驱动
Driver接口是实现部分,DriverManager是抽象部分,不同数据库厂商实现Driver, 应用通过DriverManager统一调用,不需要关心具体实现
c
Driver接口
// java.sql.Driver 接口(所有数据库驱动必须实现)
public interface Driver {
// 核心方法:创建数据库连接(不同厂商实现不同)
Connection connect(String url, Properties info) throws SQLException;
// 其他方法:判断驱动是否支持当前URL等
boolean acceptsURL(String url) throws SQLException;
// ...
}
MySQL驱动实现
// com.mysql.cj.jdbc.Driver(MySQL驱动的具体实现)
public class Driver implements java.sql.Driver {
static {
try {
// 向 DriverManager 注册自己(实现侧主动注册到抽象侧)
DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
// 实现 connect 方法:返回 MySQL 特有的 Connection
@Override
public Connection connect(String url, Properties info) throws SQLException {
// 1. 判断 URL 是否是 MySQL 格式(如 jdbc:mysql://...)
if (!acceptsURL(url)) {
return null;
}
// 2. 创建并返回 MySQL 连接(具体实现细节)
Connection conn = new com.mysql.cj.jdbc.ConnectionImpl(url, info);
return conn;
}
// ...
}
DriverManager抽象侧,桥接核心
// java.sql.DriverManager(统一管理所有 Driver 实现)
public class DriverManager {
// 缓存所有已注册的 Driver(桥接的"实现集合")
private static final CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
// 核心方法:获取连接(抽象侧调用实现侧,无需关心具体厂商)
public static Connection getConnection(String url, String user, String password) throws SQLException {
// 1. 遍历所有注册的 Driver
for (DriverInfo di : registeredDrivers) {
try {
// 2. 调用具体 Driver 的 connect 方法(桥接调用)
Connection con = di.driver.connect(url, info);
if (con != null) {
return con; // 找到支持的 Driver 即返回
}
} catch (SQLException ex) {
// 忽略不支持的 Driver,继续遍历
}
}
throw new SQLException("No suitable driver found for " + url);
}
// ...
}
八、装饰器模式
核心思想: 动态给对象添加功能,不改变原来的类
8.1 JAVA IO 流
InputStream/OutputStream的一系列装饰类,如BufferedInputStream,DataInputStream,通过嵌套装饰增强功能。InputStream 是抽象组件,FileInputStream 是具体组件,
c
抽象组件InputStream
// java.io.InputStream(所有输入流的父类,定义核心方法)
public abstract class InputStream implements Closeable {
// 核心抽象方法:读取一个字节
public abstract int read() throws IOException;
// 其他方法:读取字节数组、关闭流等
public int read(byte b[]) throws IOException { ... }
public void close() throws IOException { ... }
}
具体组件FileInoutStream
// java.io.FileInputStream(直接操作文件的具体流,无装饰)
public class FileInputStream extends InputStream {
private final FileDescriptor fd; // 底层文件描述符
// 实现 read 方法:直接从文件读取字节
@Override
public int read() throws IOException {
return read0(); // 调用 native 方法,直接操作文件
}
// native 方法(底层C实现)
private native int read0() throws IOException;
// ...
}
装饰器BufferedInputStream
// java.io.BufferedInputStream(给流添加"缓冲"功能的装饰器)
public class BufferedInputStream extends FilterInputStream {
private static final int DEFAULT_BUFFER_SIZE = 8192;
private volatile byte buf[]; // 缓冲数组(装饰器新增的功能)
// 构造器:接收一个 InputStream(被装饰的对象)
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
// 重写 read 方法:先从缓冲读,缓冲空了再调用被装饰流的 read
@Override
public int read() throws IOException {
// 1. 检查缓冲是否有数据,没有则填充(装饰器的核心逻辑)
if (pos >= count) {
fill(); // 调用被装饰流(in)的 read 填充缓冲
if (pos >= count) {
return -1; // 流结束
}
}
// 2. 从缓冲读取(增强的功能)
return buf[pos++] & 0xff;
}
// 填充缓冲:调用被装饰流的 read 方法
private void fill() throws IOException {
byte[] buffer = getBufIfOpen();
int n = in.read(buffer, 0, buffer.length); // in 是被装饰的 InputStream
if (n > 0) {
count = n;
pos = 0;
}
}
// ...
}
new BufferedInputStream(new FileInputStream("a.txt")),通过嵌套装饰,让 "文件流" 拥有了 "缓冲" 功能
九、模板模式
核心思想: 定义算法骨架,子类实现具体步骤
9.1 Spring JdbcTemplate
JdbcTemplate 封装JDBC的固定流程(获取连接,创建语句,关闭资源),将可变步骤交给用户实现
c
模板类 JdbcTemplate 核心方法
// org.springframework.jdbc.core.JdbcTemplate(JDBC 模板类)
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
// 核心方法:查询单个对象(模板方法)
@Override
public <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException {
// 调用内部模板方法,传入"可变步骤"(rowMapper)
return query(sql, args, new RowMapperResultSetExtractor<>(rowMapper, 1));
}
// 内部模板方法:封装固定流程
@Override
public <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
Assert.notNull(rse, "ResultSetExtractor must not be null");
// 固定流程1:获取数据库连接(模板负责)
Connection con = DataSourceUtils.getConnection(obtainDataSource());
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 固定流程2:创建 PreparedStatement(模板负责)
ps = createPreparedStatement(con, sql);
// 固定流程3:设置 SQL 参数(模板负责)
setValues(ps, args);
// 固定流程4:执行查询,获取 ResultSet(模板负责)
rs = ps.executeQuery();
// 可变流程:处理 ResultSet(交给 rse 实现,即用户的 RowMapper)
T result = rse.extractData(rs);
// 固定流程5:处理警告(模板负责)
handleWarnings(ps);
return result;
} catch (SQLException ex) {
// 固定流程6:异常处理(模板负责)
String sqlToUse = sql;
if (ps != null) {
sqlToUse = getSql(ps);
}
releaseResources(ps, rs);
throw translateException("Query", sqlToUse, ex);
} finally {
// 固定流程7:释放资源(模板负责,避免用户忘记关闭)
releaseResources(ps, rs);
DataSourceUtils.releaseConnection(con, obtainDataSource());
}
}
// ...
}
可变步骤 RowMapper(用户实现)
// org.springframework.jdbc.core.RowMapper(结果映射的接口,用户需实现)
public interface RowMapper<T> {
// 可变步骤:将 ResultSet 的一行映射为 Java 对象(用户定义映射规则)
T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
因此用户只需关注 "如何映射结果",无需关心连接、关闭等固定步骤:
// 用户实现 RowMapper(可变步骤)
RowMapper<User> userMapper = (rs, rowNum) -> {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
return user;
};
// 调用模板方法(固定流程由 JdbcTemplate 负责)
User user = jdbcTemplate.queryForObject("SELECT * FROM user WHERE id=?", userMapper, 1);