Spring 框架在设计和实现中大量运用了设计模式,以解决代码复用、解耦和扩展性问题。以下结合具体代码示例,说明核心设计模式及其作用:

1. 工厂模式(Factory Pattern)

作用:隐藏对象创建的细节,由工厂统一管理对象的实例化,实现创建与使用的解耦。
Spring 应用:BeanFactory 和 ApplicationContext 是工厂模式的典型实现,负责创建和管理所有 Bean。

示例代码:

// 1. 定义一个 Bean
public class UserService {
    public void sayHello() {
        System.out.println("Hello from UserService");
    }
}

// 2. Spring 配置(XML 或注解)
// 此处用注解配置:
@Configuration
public class AppConfig {
    @Bean // 工厂模式:由 Spring 容器(工厂)创建 UserService 实例
    public UserService userService() {
        return new UserService();
    }
}

// 3. 通过工厂(ApplicationContext)获取对象
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // 无需手动 new,直接从工厂获取
        UserService userService = context.getBean(UserService.class);
        userService.sayHello(); // 输出:Hello from UserService
    }
}

2. 单例模式(Singleton Pattern)

作用:确保一个类在容器中只有一个实例,减少资源消耗,适合无状态组件(如 Service、Dao)。
Spring 应用:Bean 的默认作用域为 singleton,由 DefaultSingletonBeanRegistry 管理单例缓存。

示例代码:

@Service
public class OrderService {
    // 默认单例:容器中只有一个 OrderService 实例
}

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.example");
        OrderService service1 = context.getBean(OrderService.class);
        OrderService service2 = context.getBean(OrderService.class);
        System.out.println(service1 == service2); // 输出:true(单例)
    }
}

底层实现:Spring 通过 singletonObjects 缓存池存储单例 Bean,并用双重检查锁保证线程安全:

// 简化版单例获取逻辑(Spring 源码核心逻辑)
public Object getSingleton(String beanName) {
    Object singletonObject = singletonObjects.get(beanName);
    if (singletonObject == null) {
        synchronized (this.singletonObjects) {
            singletonObject = singletonObjects.get(beanName);
            if (singletonObject == null) {
                // 创建实例并放入缓存
                singletonObject = createBean(beanName);
                singletonObjects.put(beanName, singletonObject);
            }
        }
    }
    return singletonObject;
}

3. 代理模式(Proxy Pattern)

作用:在目标对象方法执行前后插入增强逻辑(如日志、事务),不修改原代码,符合 “开闭原则”。
Spring 应用:AOP 的核心实现(JDK 动态代理或 CGLIB 代理)。

示例代码:

// 1. 目标接口和实现类
public interface UserDao {
    void save();
}

@Repository
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("保存用户数据");
    }
}

// 2. 定义切面(增强逻辑)
@Aspect
@Component
public class LogAspect {
    // 前置通知:在 save() 执行前打印日志
    @Before("execution(* com.example.UserDao.save(..))")
    public void beforeSave() {
        System.out.println("日志:准备保存用户");
    }
}

// 3. 启动类(开启 AOP)
@Configuration
@ComponentScan
@EnableAspectJAutoProxy // 开启 AOP 代理
public class AppConfig {}

// 4. 测试:调用的是代理对象
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserDao userDao = context.getBean(UserDao.class);
        userDao.save(); 
        // 输出:
        // 日志:准备保存用户
        // 保存用户数据
    }
}

原理:Spring 为 UserDaoImpl 创建代理对象,代理对象在调用 save() 时先执行 beforeSave() 增强逻辑。

4. 模板方法模式(Template Method Pattern)

作用:定义固定流程框架,将可变步骤延迟到子类实现,减少重复代码。
Spring 应用:JdbcTemplate 封装 JDBC 固定流程(连接、执行、关闭),仅暴露 SQL 和结果处理。

示例代码:

@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public User findById(Long id) {
        // 模板方法:JdbcTemplate 封装了 JDBC 固定步骤
        return jdbcTemplate.queryForObject(
            "SELECT id, name FROM user WHERE id = ?",
            new Object[]{id},
            // 可变部分:结果映射(由用户实现)
            (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"))
        );
    }
}

原理:JdbcTemplate 的 queryForObject 方法内部固定执行 “获取连接→创建语句→执行查询→处理结果→关闭资源” 流程,用户只需提供 SQL 和 RowMapper(可变部分)。

5. 观察者模式(Observer Pattern)

作用:实现对象间的解耦通信,当事件发生时,自动通知所有观察者。
Spring 应用:ApplicationEvent(事件)和 ApplicationListener(监听器)机制。

示例代码:

// 1. 定义自定义事件
public class OrderCreatedEvent extends ApplicationEvent {
    private Long orderId;
    public OrderCreatedEvent(Long orderId) {
        super(orderId);
        this.orderId = orderId;
    }
    public Long getOrderId() { return orderId; }
}

// 2. 定义观察者(监听器)
@Component
public class OrderListener implements ApplicationListener<OrderCreatedEvent> {
    @Override
    public void onApplicationEvent(OrderCreatedEvent event) {
        System.out.println("监听到订单创建:" + event.getOrderId());
    }
}

// 3. 发布事件
@Service
public class OrderService {
    @Autowired
    private ApplicationEventPublisher publisher;

    public void createOrder(Long orderId) {
        // 业务逻辑:创建订单
        System.out.println("创建订单:" + orderId);
        // 发布事件
        publisher.publishEvent(new OrderCreatedEvent(orderId));
    }
}

// 4. 测试
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.example");
        OrderService service = context.getBean(OrderService.class);
        service.createOrder(100L);
        // 输出:
        // 创建订单:100
        // 监听到订单创建:100
    }
}

6. 适配器模式(Adapter Pattern)

作用:适配不同接口,使不兼容的类可以一起工作。
Spring 应用:Spring MVC 的 HandlerAdapter 适配不同类型的处理器(如 @Controller、HttpRequestHandler)。

原理示例:
DispatcherServlet 通过 HandlerAdapter 调用不同处理器,无需关心具体类型:

// Spring MVC 核心流程(简化)
public class DispatcherServlet {
    private List<HandlerAdapter> adapters;

    public void doDispatch(HttpServletRequest request, HttpServletResponse response) {
        // 1. 找到请求对应的处理器(如 Controller)
        Object handler = getHandler(request);
        // 2. 找到适配该处理器的适配器
        HandlerAdapter adapter = getHandlerAdapter(handler);
        // 3. 通过适配器调用处理器(统一接口)
        adapter.handle(request, response, handler);
    }
}

// 不同适配器实现
public interface HandlerAdapter {
    boolean supports(Object handler); // 判断是否支持该处理器
    void handle(...) throws Exception;
}

// 适配 @Controller 注解的处理器
public class RequestMappingHandlerAdapter implements HandlerAdapter {
    @Override
    public boolean supports(Object handler) {
        return handler instanceof HandlerMethod; // 匹配 @Controller 方法
    }
    // ...
}

总结

Spring 框架通过设计模式实现了高度灵活性:

  • 工厂模式支撑 IOC 容器的 Bean 管理;
  • 代理模式是 AOP 实现的核心;
  • 模板方法模式简化了重复流程(如 JDBC);
  • 观察者模式实现了事件驱动的松耦合;
  • 适配器模式解决了 MVC 中处理器的兼容问题。

理解这些模式有助于深入掌握 Spring 的设计思想和源码逻辑。

更多推荐