❝核心洞察:装饰器模式是一种结构型模式,它通过组合的方式动态地给对象添加额外的职责,而无需修改原始类。这种"包装"思想是Spring框架实现AOP、事务、缓存等横切关注点的设计基石。
📋 模式定义与核心哲学
核心定义
装饰器模式(Decorator Pattern) 允许向一个现有的对象动态地添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
设计哲学
开放封闭原则:对扩展开放,对修改封闭 组合优于继承:通过组合而非继承来实现功能的扩展 运行时动态增强:功能的添加可以在运行时进行,更加灵活
生活比喻
❝咖啡店订单系统
基础咖啡: Espresso(组件)装饰器: MilkDecorator、SugarDecorator、WhippedCreamDecorator顾客可以任意组合: Espresso + Milk + Sugar或Espresso + WhippedCream每个装饰器都遵循相同的 Coffee接口,但添加了额外功能
🏗️ UML类图与角色解析

classDiagram
direction TB
note for Component "被装饰对象的抽象接口\n定义核心功能契约"
class Component {
<<interface>>
+operation() void
}
class ConcreteComponent {
+operation() void
}
note for Decorator "装饰器基类\n持有Component引用\n实现相同接口"
class Decorator {
-component: Component
+Decorator(Component)
+operation() void
}
class ConcreteDecoratorA {
-addedState: String
+operation() void
+addedBehavior() void
}
class ConcreteDecoratorB {
+operation() void
}
Component <|.. ConcreteComponent : 实现
Component <|.. Decorator : 实现
Decorator o-- Component : 包装
Decorator <|-- ConcreteDecoratorA : 继承
Decorator <|-- ConcreteDecoratorB : 继承
%% 方法调用流程
note for ConcreteDecoratorA "装饰器可以在调用前后添加额外行为"
ConcreteDecoratorA : +operation() {
.. 前处理 ..
component.operation()
.. 后处理 ..
}
模式角色详解
| Component(组件) | BeanMethodInvocation、HttpServletRequest | |
| ConcreteComponent(具体组件) | Service、Controller、Repository | |
| Decorator(装饰器) | BeanPostProcessorMethodInterceptor、Filter | |
| ConcreteDecorator(具体装饰器) | TransactionInterceptorCacheInterceptor、LoggingFilter |
🌟 Spring中的装饰器模式应用
应用1:BeanPostProcessor - Spring IoC的装饰器模式典范
设计洞察
Spring需要在Bean生命周期的特定阶段动态增强Bean的功能,而不修改Bean本身的代码。BeanPostProcessor提供了这种装饰能力。
源码解析
// 🍃 组件接口:普通的Spring Bean
@Component
publicclassUserService{
private String serviceName = "DefaultUserService";
@PostConstruct
publicvoidinit(){
System.out.println("UserService初始化完成");
}
public User findUserById(Long id){
// 模拟数据库查询
returnnew User(id, "用户" + id);
}
publicvoidupdateUser(User user){
System.out.println("更新用户: " + user.getName());
}
}
// 🎨 装饰器接口:BeanPostProcessor
publicinterfaceBeanPostProcessor{
/**
* 在Bean初始化之前执行
* 可以修改Bean的属性值
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean; // 默认不修改
}
/**
* 在Bean初始化之后执行
* 可以返回包装后的Bean(代理对象)
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean; // 默认不修改
}
}
// 🌈 具体装饰器1:属性验证装饰器
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
publicclassValidationBeanPostProcessorimplementsBeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// 检查Bean是否实现了Validatable接口
if (bean instanceof Validatable) {
Validatable validatable = (Validatable) bean;
try {
validatable.validate(); // 执行验证
System.out.println("✅ Bean验证通过: " + beanName);
} catch (ValidationException e) {
System.err.println("❌ Bean验证失败: " + beanName + " - " + e.getMessage());
thrownew BeanInitializationException("Bean验证失败", e);
}
}
return bean;
}
}
// 🌈 具体装饰器2:性能监控装饰器
@Component
@Order(Ordered.LOWEST_PRECEDENCE) // 最低优先级
publicclassMonitoringBeanPostProcessorimplementsBeanPostProcessor{
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// 只为Service层的Bean创建监控代理
Class<?> beanClass = bean.getClass();
if (beanClass.isAnnotationPresent(Service.class) ||
beanClass.isAnnotationPresent(Component.class)) {
// 创建JDK动态代理(装饰Bean)
return Proxy.newProxyInstance(
beanClass.getClassLoader(),
beanClass.getInterfaces(),
new MonitoringInvocationHandler(bean, beanName)
);
}
return bean;
}
// 监控调用处理器
privatestaticclassMonitoringInvocationHandlerimplementsInvocationHandler{
privatefinal Object target;
privatefinal String beanName;
privatefinal Map<String, MethodMetrics> metrics = new ConcurrentHashMap<>();
publicMonitoringInvocationHandler(Object target, String beanName){
this.target = target;
this.beanName = beanName;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodKey = method.getName();
long startTime = System.currentTimeMillis();
try {
// 调用原始方法
Object result = method.invoke(target, args);
recordSuccess(methodKey, startTime);
return result;
} catch (InvocationTargetException e) {
recordFailure(methodKey, startTime, e.getTargetException());
throw e.getTargetException();
} finally {
// 定期输出监控报告
if (System.currentTimeMillis() % 10000 < 100) { // 每10秒输出一次
outputMetricsReport();
}
}
}
privatevoidrecordSuccess(String methodName, long startTime){
MethodMetrics metric = metrics.computeIfAbsent(
methodName, k -> new MethodMetrics());
metric.incrementSuccess();
metric.recordDuration(System.currentTimeMillis() - startTime);
}
privatevoidoutputMetricsReport(){
System.out.println("=== 监控报告 ===");
metrics.forEach((method, metric) -> {
System.out.printf("%s.%s: 调用%d次, 平均耗时%.2fms%n",
beanName, method, metric.getTotalCount(), metric.getAverageDuration());
});
}
}
}
// 🌈 具体装饰器3:审计日志装饰器
@Component
publicclassAuditLogBeanPostProcessorimplementsBeanPostProcessor{
privatefinal ThreadLocal<AuditContext> auditContext = new ThreadLocal<>();
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// 为Repository添加审计日志
if (bean.getClass().isAnnotationPresent(Repository.class)) {
return Enhancer.create(
bean.getClass(),
new AuditLogMethodInterceptor(bean, beanName)
);
}
return bean;
}
privatestaticclassAuditLogMethodInterceptorimplementsMethodInterceptor{
privatefinal Object target;
privatefinal String beanName;
publicAuditLogMethodInterceptor(Object target, String beanName){
this.target = target;
this.beanName = beanName;
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy)throws Throwable {
String auditMessage = String.format(
"审计日志 - 类: %s, 方法: %s, 参数: %s",
beanName, method.getName(), Arrays.toString(args)
);
AuditLogger.log(auditMessage);
long startTime = System.currentTimeMillis();
try {
Object result = method.invoke(target, args);
AuditLogger.log(String.format("方法执行成功, 耗时: %dms",
System.currentTimeMillis() - startTime));
return result;
} catch (Exception e) {
AuditLogger.log(String.format("方法执行失败: %s", e.getMessage()));
throw e;
}
}
}
}
装饰器链执行流程
// Spring容器中的BeanPostProcessor执行顺序
publicabstractclassAbstractAutowireCapableBeanFactory{
protected Object initializeBean(String beanName, Object bean,
@Nullable RootBeanDefinition mbd){
// 1. 应用BeanPostProcessors的before初始化方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 2. 调用Bean的初始化方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
thrownew BeanCreationException("初始化失败", ex);
}
// 3. 应用BeanPostProcessors的after初始化方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
// 装饰器链:按顺序执行所有BeanPostProcessor
public Object applyBeanPostProcessorsBeforeInitialization(Object bean, String beanName)
throws BeansException {
Object result = bean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result; // 某个处理器返回null,停止链
}
result = current; // 每个处理器可能返回包装后的对象
}
return result;
}
}
使用示例
@Configuration
publicclassBeanPostProcessorConfig{
@Bean
publicstatic ValidationBeanPostProcessor validationBeanPostProcessor(){
returnnew ValidationBeanPostProcessor();
}
@Bean
publicstatic MonitoringBeanPostProcessor monitoringBeanPostProcessor(){
returnnew MonitoringBeanPostProcessor();
}
@Bean
publicstatic AuditLogBeanPostProcessor auditLogBeanPostProcessor(){
returnnew AuditLogBeanPostProcessor();
}
// 注意:BeanPostProcessor的@Bean方法必须是static的
// 否则会导致过早初始化,影响其他Bean的装饰
}
// 测试装饰器效果
@SpringBootTest
classBeanPostProcessorTest{
@Autowired
private UserService userService; // 已经被多个装饰器包装
@Test
voidtestDecoratedBean(){
// 这个userService实际上是被包装过的:
// 1. 经过了ValidationBeanPostProcessor的验证
// 2. 被MonitoringBeanPostProcessor包装了性能监控
// 3. 如果是Repository,还被AuditLogBeanPostProcessor包装了审计日志
User user = userService.findUserById(1L);
assertNotNull(user);
// 调用会被监控和记录
userService.updateUser(user);
}
}
应用2:Spring AOP - 方法级别的装饰器模式
设计洞察
Spring AOP通过动态代理实现方法级别的装饰,可以在方法调用前后添加横切关注点(日志、事务、安全等)。
源码解析
// 🍃 组件:被代理的目标对象
@Service
publicclassOrderServiceImplimplementsOrderService{
@Override
@Transactional
public Order createOrder(OrderRequest request){
// 业务逻辑
Order order = new Order();
order.setId(UUID.randomUUID().toString());
order.setAmount(request.getAmount());
order.setStatus(OrderStatus.CREATED);
// 保存到数据库
orderRepository.save(order);
// 发送事件
applicationEventPublisher.publishEvent(new OrderCreatedEvent(this, order));
return order;
}
@Override
@Cacheable(value = "orders", key = "#orderId")
public Order getOrder(String orderId){
return orderRepository.findById(orderId)
.orElseThrow(() -> new OrderNotFoundException("订单不存在"));
}
@Override
@CacheEvict(value = "orders", key = "#orderId")
publicvoidcancelOrder(String orderId){
Order order = getOrder(orderId);
order.setStatus(OrderStatus.CANCELLED);
orderRepository.save(order);
}
}
// 🎨 装饰器接口:MethodInterceptor
publicinterfaceMethodInterceptorextendsInterceptor{
/**
* 实现此方法以在方法调用前后添加额外行为
* @param invocation 方法调用信息
* @return 方法调用结果
* @throws Throwable 可能抛出的异常
*/
Object invoke(MethodInvocation invocation)throws Throwable;
}
// 🌈 具体装饰器1:事务拦截器
@Component
publicclassTransactionInterceptorimplementsMethodInterceptor, Ordered{
privatefinal PlatformTransactionManager transactionManager;
privatefinal TransactionAttributeSource transactionAttributeSource;
publicTransactionInterceptor(PlatformTransactionManager transactionManager,
TransactionAttributeSource transactionAttributeSource){
this.transactionManager = transactionManager;
this.transactionAttributeSource = transactionAttributeSource;
}
@Override
public Object invoke(MethodInvocation invocation)throws Throwable {
// 获取事务属性(@Transactional注解的信息)
Method method = invocation.getMethod();
Class<?> targetClass = invocation.getThis() != null ?
invocation.getThis().getClass() : null;
TransactionAttribute txAttr = transactionAttributeSource
.getTransactionAttribute(method, targetClass);
// 如果没有@Transactional注解,直接执行方法
if (txAttr == null) {
return invocation.proceed();
}
// 确定事务管理器
PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 创建事务
TransactionStatus status = tm.getTransaction(txAttr);
try {
// 执行被装饰的方法
Object result = invocation.proceed();
// 提交事务
tm.commit(status);
return result;
} catch (Throwable ex) {
// 根据异常类型决定是回滚还是提交
completeTransactionAfterThrowing(status, txAttr, ex);
throw ex;
}
}
@Override
publicintgetOrder(){
return Ordered.HIGHEST_PRECEDENCE + 1; // 高优先级
}
}
// 🌈 具体装饰器2:缓存拦截器
@Component
publicclassCacheInterceptorimplementsMethodInterceptor, Ordered{
privatefinal CacheManager cacheManager;
privatefinal KeyGenerator keyGenerator;
publicCacheInterceptor(CacheManager cacheManager, KeyGenerator keyGenerator){
this.cacheManager = cacheManager;
this.keyGenerator = keyGenerator;
}
@Override
public Object invoke(MethodInvocation invocation)throws Throwable {
// 获取缓存注解
Method method = invocation.getMethod();
Cacheable cacheable = method.getAnnotation(Cacheable.class);
CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
if (cacheable != null) {
return handleCacheable(invocation, cacheable);
} elseif (cacheEvict != null) {
return handleCacheEvict(invocation, cacheEvict);
} else {
return invocation.proceed();
}
}
private Object handleCacheable(MethodInvocation invocation, Cacheable cacheable)
throws Throwable {
// 生成缓存key
Object key = keyGenerator.generate(invocation.getThis(),
invocation.getMethod(),
invocation.getArguments());
// 获取缓存
Cache cache = cacheManager.getCache(cacheable.value());
ValueWrapper cachedValue = cache.get(key);
if (cachedValue != null) {
// 缓存命中,直接返回
System.out.println("缓存命中: " + cacheable.value() + " - " + key);
return cachedValue.get();
}
// 缓存未命中,执行方法
Object result = invocation.proceed();
// 将结果放入缓存
if (result != null) {
cache.put(key, result);
System.out.println("缓存写入: " + cacheable.value() + " - " + key);
}
return result;
}
@Override
publicintgetOrder(){
return Ordered.LOWEST_PRECEDENCE - 1; // 低优先级
}
}
// 🌈 具体装饰器3:性能监控拦截器
@Component
publicclassPerformanceMonitorInterceptorimplementsMethodInterceptor{
privatestaticfinal Logger logger = LoggerFactory
.getLogger(PerformanceMonitorInterceptor.class);
@Override
public Object invoke(MethodInvocation invocation)throws Throwable {
String className = invocation.getMethod().getDeclaringClass().getSimpleName();
String methodName = invocation.getMethod().getName();
String fullMethodName = className + "." + methodName;
long startTime = System.currentTimeMillis();
logger.info("开始执行: {}", fullMethodName);
try {
Object result = invocation.proceed();
long duration = System.currentTimeMillis() - startTime;
if (duration > 1000) { // 超过1秒记录警告
logger.warn("方法执行缓慢: {} 耗时 {}ms", fullMethodName, duration);
} else {
logger.info("方法执行完成: {} 耗时 {}ms", fullMethodName, duration);
}
return result;
} catch (Exception e) {
logger.error("方法执行异常: {} - {}", fullMethodName, e.getMessage(), e);
throw e;
}
}
}
AOP代理创建过程
// AOP代理工厂:创建装饰器链
publicclassProxyFactoryextendsProxyCreatorSupport{
public Object getProxy(){
return createAopProxy().getProxy();
}
protectedfinalsynchronized AopProxy createAopProxy(){
if (!isActive()) {
activate();
}
// 获取所有Advisor(装饰器链)
List<Advisor> advisors = getAdvisors();
// 根据条件选择JDK动态代理或CGLIB代理
if (isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces()) {
Class<?> targetClass = getTargetClass();
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
returnnew JdkDynamicAopProxy(this);
}
returnnew ObjenesisCglibAopProxy(this);
} else {
returnnew JdkDynamicAopProxy(this);
}
}
}
// 装饰器链的执行
publicclassReflectiveMethodInvocationimplementsProxyMethodInvocation{
privatefinal Object proxy;
privatefinal Object target;
privatefinal Method method;
privatefinal Object[] arguments;
privatefinal List<Object> interceptorsAndDynamicMethodMatchers;
privateint currentInterceptorIndex = -1;
@Override
public Object proceed()throws Throwable {
// 如果已经执行到装饰器链的末尾,执行原始方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个装饰器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 执行装饰器
if (interceptorOrInterceptionAdvice instanceof MethodInterceptor) {
MethodInterceptor mi = (MethodInterceptor) interceptorOrInterceptionAdvice;
return mi.invoke(this); // 递归调用
} else {
// 动态方法匹配器
return invokeJoinpoint();
}
}
}
配置与使用
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableTransactionManagement
@EnableCaching
publicclassAopConfig{
@Bean
public TransactionInterceptor transactionInterceptor(
PlatformTransactionManager transactionManager){
returnnew TransactionInterceptor(transactionManager,
new AnnotationTransactionAttributeSource());
}
@Bean
public CacheInterceptor cacheInterceptor(
CacheManager cacheManager, KeyGenerator keyGenerator){
returnnew CacheInterceptor(cacheManager, keyGenerator);
}
@Bean
public PerformanceMonitorInterceptor performanceMonitorInterceptor(){
returnnew PerformanceMonitorInterceptor();
}
@Bean
public Advisor transactionAdvisor(TransactionInterceptor interceptor){
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("@annotation(org.springframework.transaction.annotation.Transactional)");
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(interceptor);
advisor.setOrder(Ordered.HIGHEST_PRECEDENCE);
return advisor;
}
@Bean
public Advisor cacheAdvisor(CacheInterceptor interceptor){
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("@annotation(org.springframework.cache.annotation.Cacheable) || " +
"@annotation(org.springframework.cache.annotation.CacheEvict)");
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(interceptor);
advisor.setOrder(Ordered.LOWEST_PRECEDENCE);
return advisor;
}
@Bean
public Advisor performanceAdvisor(PerformanceMonitorInterceptor interceptor){
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* com.example.service.*.*(..))");
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(interceptor);
return advisor;
}
}
应用3:Servlet Filter Chain - Web请求的装饰器链
设计洞察
Servlet Filter是HTTP请求处理管道中的装饰器,每个Filter都可以在请求到达Servlet之前和响应返回客户端之后添加处理逻辑。
源码解析
// 🍃 组件:HttpServletRequest/HttpServletResponse
publicinterfaceHttpServletRequest{
// 原始请求接口
}
publicinterfaceHttpServletResponse{
// 原始响应接口
}
// 🎨 装饰器接口:Filter
publicinterfaceFilter{
voidinit(FilterConfig filterConfig)throws ServletException;
voiddoFilter(ServletRequest request, ServletResponse response,
FilterChain chain)throws IOException, ServletException;
voiddestroy();
}
// 🌈 具体装饰器1:认证过滤器
@Component
@Order(1) // 最先执行
publicclassAuthenticationFilterextendsOncePerRequestFilter{
privatefinal AuthenticationService authService;
privatefinal JwtTokenProvider tokenProvider;
publicAuthenticationFilter(AuthenticationService authService,
JwtTokenProvider tokenProvider){
this.authService = authService;
this.tokenProvider = tokenProvider;
}
@Override
protectedvoiddoFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
// 1. 从请求中提取Token
String token = extractToken(request);
if (token == null) {
// 无Token,继续下一个过滤器(可能是公开接口)
filterChain.doFilter(request, response);
return;
}
// 2. 验证Token
if (!tokenProvider.validateToken(token)) {
sendError(response, HttpStatus.UNAUTHORIZED, "Token无效或已过期");
return;
}
// 3. 获取用户信息
String username = tokenProvider.getUsernameFromToken(token);
UserDetails userDetails = authService.loadUserByUsername(username);
if (userDetails == null) {
sendError(response, HttpStatus.UNAUTHORIZED, "用户不存在");
return;
}
// 4. 设置认证信息到SecurityContext
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null,
userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 5. 继续过滤器链
filterChain.doFilter(request, response);
// 6. 请求处理完成后清理(后处理)
SecurityContextHolder.clearContext();
}
private String extractToken(HttpServletRequest request){
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
returnnull;
}
}
// 🌈 具体装饰器2:日志过滤器
@Component
@Order(2)
publicclassRequestLoggingFilterextendsOncePerRequestFilter{
privatestaticfinal Logger logger = LoggerFactory
.getLogger(RequestLoggingFilter.class);
@Override
protectedvoiddoFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
long startTime = System.currentTimeMillis();
String requestId = UUID.randomUUID().toString();
// 包装请求和响应以便多次读取
ContentCachingRequestWrapper wrappedRequest =
new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper wrappedResponse =
new ContentCachingResponseWrapper(response);
// 记录请求开始
logRequestStart(wrappedRequest, requestId);
try {
// 继续过滤器链
filterChain.doFilter(wrappedRequest, wrappedResponse);
// 记录请求完成
long duration = System.currentTimeMillis() - startTime;
logRequestComplete(wrappedRequest, wrappedResponse, requestId, duration);
} finally {
// 确保响应内容被复制回原始响应
wrappedResponse.copyBodyToResponse();
}
}
privatevoidlogRequestStart(HttpServletRequest request, String requestId){
MDC.put("requestId", requestId);
logger.info("请求开始: {} {}, 客户端IP: {}, User-Agent: {}",
request.getMethod(), request.getRequestURI(),
request.getRemoteAddr(), request.getHeader("User-Agent"));
// 记录请求体(如果是可读的内容类型)
String contentType = request.getContentType();
if (contentType != null && contentType.contains("application/json")) {
String requestBody = getRequestBody(request);
if (StringUtils.hasText(requestBody)) {
logger.debug("请求体: {}", requestBody);
}
}
}
}
// 🌈 具体装饰器3:响应压缩过滤器
@Component
@Order(Ordered.LOWEST_PRECEDENCE) // 最后执行
publicclassGzipCompressionFilterextendsOncePerRequestFilter{
@Override
protectedvoiddoFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
// 检查客户端是否支持gzip
String acceptEncoding = request.getHeader("Accept-Encoding");
boolean supportsGzip = acceptEncoding != null &&
(acceptEncoding.contains("gzip") || acceptEncoding.contains("deflate"));
if (!supportsGzip) {
// 客户端不支持压缩,直接继续
filterChain.doFilter(request, response);
return;
}
// 包装响应以支持压缩
GzipResponseWrapper gzipResponse = new GzipResponseWrapper(response);
try {
filterChain.doFilter(request, gzipResponse);
} finally {
gzipResponse.finish();
}
}
// 压缩包装器
privatestaticclassGzipResponseWrapperextendsHttpServletResponseWrapper{
private GZIPOutputStream gzipOutputStream;
private ServletOutputStream servletOutputStream;
private PrintWriter printWriter;
publicGzipResponseWrapper(HttpServletResponse response)throws IOException {
super(response);
response.setHeader("Content-Encoding", "gzip");
}
@Override
public ServletOutputStream getOutputStream()throws IOException {
if (this.servletOutputStream == null) {
this.servletOutputStream = new FilterServletOutputStream(
new GZIPOutputStream(super.getOutputStream())
);
}
returnthis.servletOutputStream;
}
publicvoidfinish()throws IOException {
if (this.gzipOutputStream != null) {
this.gzipOutputStream.finish();
}
}
}
}
Filter Chain执行机制
// Spring的FilterChain实现
publicclassFilterChainProxyextendsGenericFilterBean{
private List<SecurityFilterChain> filterChains;
@Override
publicvoiddoFilter(ServletRequest request, ServletResponse response,
FilterChain chain)throws IOException, ServletException {
// 获取当前请求匹配的过滤器链
List<Filter> filters = getFilters(request);
if (filters == null || filters.size() == 0) {
// 无过滤器,直接继续
chain.doFilter(request, response);
return;
}
// 创建虚拟过滤器链
VirtualFilterChain virtualFilterChain =
new VirtualFilterChain(chain, filters);
// 执行过滤器链
virtualFilterChain.doFilter(request, response);
}
// 虚拟过滤器链:按顺序执行所有过滤器
privatestaticclassVirtualFilterChainimplementsFilterChain{
privatefinal FilterChain originalChain;
privatefinal List<Filter> additionalFilters;
privateint currentPosition = 0;
publicVirtualFilterChain(FilterChain chain, List<Filter> additionalFilters){
this.originalChain = chain;
this.additionalFilters = additionalFilters;
}
@Override
publicvoiddoFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (this.currentPosition == this.additionalFilters.size()) {
// 所有过滤器执行完毕,执行原始链
this.originalChain.doFilter(request, response);
} else {
// 执行下一个过滤器
this.currentPosition++;
Filter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}
}
}
⚖️ 装饰器模式与其他模式的对比
装饰器 vs 代理模式
| 设计目的 | 增强功能 | 控制访问 |
| 关注点 | ||
| 关系类型 | ||
| 创建时机 | ||
| 透明性 | ||
| Spring示例 | BeanPostProcessorMethodInterceptor | ProxyFactoryJdkDynamicAopProxy |
| 典型应用 |
装饰器 vs 适配器模式
| 目的 | 增强功能 | 转换接口 |
| 接口变化 | ||
| 对象关系 | ||
| 设计阶段 |
装饰器 vs 责任链模式
| 结构 | ||
| 执行顺序 | ||
| 停止条件 | ||
| 典型应用 |
📊 Spring装饰器模式应用全景
| Bean生命周期 | BeanPostProcessor | AutowiredAnnotationBeanPostProcessor | ||
| AOP增强 | MethodInterceptor | TransactionInterceptor | ||
| 缓存管理 | MethodInterceptor | CacheInterceptor | ||
| Servlet处理 | Filter | AuthenticationFilter | ||
| 响应处理 | ResponseBodyAdvice | ResponseWrapperAdvice | ||
| 消息处理 | MessageListenerAdapter | MessagingInterceptor | ||
| 事件处理 | ApplicationListener | TransactionalEventListener |
🎯 装饰器模式的优势与最佳实践
设计优势
开闭原则:无需修改现有代码即可添加新功能 单一职责:每个装饰器只关注一个横切关注点 运行时灵活性:装饰器可以在运行时动态组合 避免类爆炸:相比继承,组合方式更加灵活 可逆性:装饰器可以按需添加或移除
最佳实践
保持装饰器轻量级:每个装饰器应只负责单一功能 注意装饰顺序:某些装饰器有执行顺序要求(如事务装饰器应在最外层) 避免循环装饰:防止装饰器相互包装导致无限递归 考虑性能影响:过多的装饰器会影响性能,需合理设计 提供配置选项:允许通过配置启用/禁用特定装饰器
Spring中的最佳实践
// 1. 合理设置装饰器顺序
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 高优先级装饰器
publicclassValidationDecoratorimplementsBeanPostProcessor{ }
@Component
@Order(Ordered.LOWEST_PRECEDENCE) // 低优先级装饰器
publicclassLoggingDecoratorimplementsBeanPostProcessor{ }
// 2. 使用条件装饰
@Component
@ConditionalOnProperty(name = "app.feature.caching", havingValue = "true")
publicclassCachingDecoratorimplementsBeanPostProcessor{ }
// 3. 避免过早初始化
@Configuration
publicclassDecoratorConfig{
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE) // 标记为基础设施Bean
publicstatic MyBeanPostProcessor myBeanPostProcessor(){
returnnew MyBeanPostProcessor(); // 静态方法避免循环依赖
}
}
// 4. 使用组合装饰器
@Component
publicclassCompositeDecoratorimplementsBeanPostProcessor{
privatefinal List<BeanPostProcessor> decorators;
publicCompositeDecorator(List<BeanPostProcessor> decorators){
this.decorators = decorators.stream()
.filter(decorator -> decorator != this) // 排除自身
.collect(Collectors.toList());
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName){
Object result = bean;
for (BeanPostProcessor decorator : decorators) {
result = decorator.postProcessBeforeInitialization(result, beanName);
}
return result;
}
}
🚨 常见陷阱与解决方案
陷阱1:装饰器顺序问题
// ❌ 错误:事务装饰器在内层,日志在外层
// 如果事务回滚,日志仍然会记录"操作成功"
@Order(1)
publicclassLoggingDecoratorimplementsMethodInterceptor{
public Object invoke(MethodInvocation invocation)throws Throwable {
logger.info("开始执行");
try {
Object result = invocation.proceed();
logger.info("执行成功"); // 事务回滚时这里仍然会执行!
return result;
} catch (Exception e) {
logger.error("执行失败", e);
throw e;
}
}
}
@Order(2) // 顺序错误
publicclassTransactionDecoratorimplementsMethodInterceptor{
public Object invoke(MethodInvocation invocation)throws Throwable {
TransactionStatus status = transactionManager.begin();
try {
return invocation.proceed();
} catch (Exception e) {
transactionManager.rollback(status); // 回滚事务
throw e;
}
}
}
// ✅ 正确:事务装饰器在外层,日志在内层
@Order(1) // 高优先级,先执行
publicclassTransactionDecoratorimplementsMethodInterceptor{
public Object invoke(MethodInvocation invocation)throws Throwable {
TransactionStatus status = transactionManager.begin();
try {
return invocation.proceed(); // 调用内层的日志装饰器
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
}
}
@Order(2) // 低优先级,后执行
publicclassLoggingDecoratorimplementsMethodInterceptor{
public Object invoke(MethodInvocation invocation)throws Throwable {
logger.info("开始执行");
try {
Object result = invocation.proceed(); // 调用原始方法
logger.info("执行成功");
return result;
} catch (Exception e) {
logger.error("执行失败", e);
throw e;
}
}
}
陷阱2:装饰器循环依赖
// ❌ 错误:装饰器相互依赖导致循环
@Component
publicclassDecoratorAimplementsBeanPostProcessor{
@Autowired
private DecoratorB decoratorB; // 循环依赖!
@Override
public Object postProcessAfterInitialization(Object bean, String beanName){
// 使用decoratorB...
return bean;
}
}
@Component
publicclassDecoratorBimplementsBeanPostProcessor{
@Autowired
private DecoratorA decoratorA; // 循环依赖!
@Override
public Object postProcessAfterInitialization(Object bean, String beanName){
// 使用decoratorA...
return bean;
}
}
// ✅ 正确:避免装饰器间的直接依赖
@Component
publicclassDecoratorAimplementsBeanPostProcessor{
// 不直接依赖其他装饰器
@Override
public Object postProcessAfterInitialization(Object bean, String beanName){
// 独立处理
return processA(bean);
}
}
@Component
publicclassDecoratorBimplementsBeanPostProcessor{
// 不直接依赖其他装饰器
@Override
public Object postProcessAfterInitialization(Object bean, String beanName){
// 独立处理
return processB(bean);
}
}
// 通过组合器管理执行顺序
@Component
publicclassDecoratorOrchestrator{
privatefinal List<BeanPostProcessor> decorators;
publicDecoratorOrchestrator(List<BeanPostProcessor> decorators){
// 按Order排序
this.decorators = decorators.stream()
.sorted(AnnotationAwareOrderComparator.INSTANCE)
.collect(Collectors.toList());
}
}
🛠️ 实战练习
练习1:实现可配置的装饰器链
// 任务:创建一个可动态配置的装饰器框架
// 要求:
// 1. 支持通过配置文件启用/禁用特定装饰器
// 2. 支持自定义装饰器执行顺序
// 3. 支持装饰器条件执行(基于Bean类型、方法注解等)
@Configuration
@EnableConfigurationProperties(DecoratorProperties.class)
publicclassConfigurableDecoratorConfig{
@Bean
public ConfigurableBeanPostProcessor configurableBeanPostProcessor(
DecoratorProperties properties,
List<Decorator> availableDecorators){
// 1. 根据配置筛选启用的装饰器
List<Decorator> enabledDecorators = availableDecorators.stream()
.filter(decorator -> isDecoratorEnabled(properties, decorator))
.collect(Collectors.toList());
// 2. 按配置排序
enabledDecorators.sort(Comparator.comparingInt(
decorator -> getDecoratorOrder(properties, decorator)));
returnnew ConfigurableBeanPostProcessor(enabledDecorators);
}
privatebooleanisDecoratorEnabled(DecoratorProperties properties, Decorator decorator){
String decoratorName = decorator.getClass().getSimpleName();
return properties.getEnabledDecorators().contains(decoratorName);
}
}
// 配置类
@ConfigurationProperties(prefix = "app.decorators")
@Data
publicclassDecoratorProperties{
private List<String> enabledDecorators = Arrays.asList(
"ValidationDecorator", "LoggingDecorator", "CachingDecorator");
private Map<String, Integer> decoratorOrders = new HashMap<>();
publicDecoratorProperties(){
decoratorOrders.put("ValidationDecorator", 100);
decoratorOrders.put("TransactionDecorator", 200);
decoratorOrders.put("CachingDecorator", 300);
decoratorOrders.put("LoggingDecorator", 400);
}
}
// 配置文件 application.yml
app:
decorators:
enabled-decorators:
- ValidationDecorator
- TransactionDecorator
- CachingDecorator
decorator-orders:
ValidationDecorator: 100
TransactionDecorator: 200
CachingDecorator: 300
练习2:装饰器性能监控
// 任务:监控装饰器的性能影响
// 要求:
// 1. 记录每个装饰器的执行时间
// 2. 统计装饰器命中率
// 3. 支持性能报告输出
@Component
publicclassDecoratorMetricsCollector{
privatefinal Map<String, DecoratorMetrics> metricsMap = new ConcurrentHashMap<>();
publicvoidrecordExecution(String decoratorName, long duration, boolean success){
DecoratorMetrics metrics = metricsMap.computeIfAbsent(
decoratorName, k -> new DecoratorMetrics());
metrics.recordExecution(duration, success);
}
public DecoratorReport generateReport(){
DecoratorReport report = new DecoratorReport();
metricsMap.forEach((decoratorName, metrics) -> {
DecoratorStats stats = new DecoratorStats();
stats.setTotalExecutions(metrics.getTotalExecutions());
stats.setSuccessCount(metrics.getSuccessCount());
stats.setAverageDuration(metrics.getAverageDuration());
stats.setP95Duration(metrics.getPercentileDuration(95));
stats.setP99Duration(metrics.getPercentileDuration(99));
report.addDecoratorStats(decoratorName, stats);
});
return report;
}
// 装饰器包装器:自动收集指标
publicstaticclassMonitoringDecoratorWrapperimplementsBeanPostProcessor{
privatefinal BeanPostProcessor delegate;
privatefinal DecoratorMetricsCollector metricsCollector;
publicMonitoringDecoratorWrapper(BeanPostProcessor delegate,
DecoratorMetricsCollector metricsCollector){
this.delegate = delegate;
this.metricsCollector = metricsCollector;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName){
long startTime = System.nanoTime();
try {
Object result = delegate.postProcessBeforeInitialization(bean, beanName);
long duration = System.nanoTime() - startTime;
metricsCollector.recordExecution(delegate.getClass().getSimpleName(),
duration, true);
return result;
} catch (Exception e) {
long duration = System.nanoTime() - startTime;
metricsCollector.recordExecution(delegate.getClass().getSimpleName(),
duration, false);
throw e;
}
}
}
}
📈 性能优化建议
1. 懒加载装饰器
@Component
publicclassLazyDecoratorimplementsBeanPostProcessor, SmartInitializingSingleton{
privatevolatileboolean initialized = false;
privatefinal Object lock = new Object();
@Override
public Object postProcessAfterInitialization(Object bean, String beanName){
if (!initialized) {
synchronized (lock) {
if (!initialized) {
// 延迟初始化装饰器资源
initializeDecorator();
initialized = true;
}
}
}
// 执行装饰逻辑
return decorate(bean);
}
@Override
publicvoidafterSingletonsInstantiated(){
// 所有单例Bean初始化完成后执行
preWarmDecoratorCache();
}
}
2. 装饰器缓存
@Component
publicclassCachingDecoratorimplementsBeanPostProcessor{
privatefinal CacheManager cacheManager;
privatefinal Map<Class<?>, Boolean> decoratorCache = new ConcurrentHashMap<>();
@Override
public Object postProcessAfterInitialization(Object bean, String beanName){
Class<?> beanClass = bean.getClass();
// 检查缓存
Boolean shouldDecorate = decoratorCache.get(beanClass);
if (shouldDecorate == null) {
// 计算是否需要装饰(可能较耗时)
shouldDecorate = shouldDecorate(bean);
decoratorCache.put(beanClass, shouldDecorate);
}
if (shouldDecorate) {
return doDecorate(bean);
}
return bean;
}
}
3. 并行装饰
@Component
publicclassParallelDecoratorimplementsBeanPostProcessor{
privatefinal ExecutorService executor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors());
@Override
public Object postProcessAfterInitialization(Object bean, String beanName){
List<Callable<Object>> tasks = createDecorationTasks(bean);
try {
// 并行执行独立的装饰任务
List<Future<Object>> futures = executor.invokeAll(tasks);
// 合并装饰结果
Object result = bean;
for (Future<Object> future : futures) {
result = future.get();
}
return result;
} catch (InterruptedException | ExecutionException e) {
thrownew BeanCreationException("装饰器执行失败", e);
}
}
}
🎯 关键要点总结
动态增强:装饰器模式允许在运行时动态添加功能 开闭原则:无需修改现有代码即可扩展功能 组合优于继承:通过组合实现功能的灵活叠加 透明包装:装饰器和被装饰对象实现相同接口 Spring应用: BeanPostProcessor、AOP拦截器、Servlet Filter都是装饰器模式的实现装饰器链:多个装饰器可以形成链式调用,注意执行顺序 性能考量:合理设计装饰器,避免过度装饰影响性能
📚 扩展学习资源
推荐阅读
Spring官方文档:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/aopalliance/intercept/MethodInterceptor.html https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop 设计模式进阶:
《设计模式:可复用面向对象软件的基础》- 装饰器模式章节 《Head First设计模式》- 装饰对象章节 《Effective Java》- 组合优于继承原则 相关设计模式:
代理模式(控制访问) 适配器模式(接口转换) 责任链模式(处理链传递)
实践项目建议
自定义注解处理器:实现类似 @Transactional的自定义注解装饰器插件化系统:基于装饰器模式实现可插拔的功能模块 中间件开发:实现类似Filter的请求处理装饰器链 监控系统:为应用添加可配置的性能监控装饰器
🚀 下一步:外观模式
掌握了装饰器模式的动态增强能力后,接下来可以学习外观模式,它关注如何为复杂的子系统提供统一的简化接口。
👉 12.外观模式 (Facade Pattern) - Spring案例:为复杂的子系统提供一个统一的接口,使子系统更易于使用。
夜雨聆风