系列文章目录
文章目录
- 系列文章目录
- 一、单例模式
- 二、工厂模式
- 三、代理模式
- 
- [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);