You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Struts 1与Spring整合及Spring AOP+AspectJ实现方法拦截审计

我之前刚好搞定过Struts 1 + Spring整合并通过AspectJ实现无侵入式审计的需求,给你一步步梳理操作细节,全程不用改原有业务类,放心跟着来:

第一步:完成Struts 1与Spring的整合

这是实现AOP的基础,核心是让Spring接管Struts的Action实例,同时加载Spring上下文。

1.1 配置web.xml

替换原生Struts的ActionServlet为Spring提供的代理类,同时添加Spring上下文加载监听器:

<!-- Spring上下文配置 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Struts 1 代理ActionServlet配置 -->
<servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.springframework.web.struts.DelegatingActionProxy</servlet-class>
    <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

关键说明:DelegatingActionProxy会把Action的创建权交给Spring,这样Spring才能对Action或其依赖的业务类做AOP增强。

1.2 配置struts-config.xml

指定Spring的请求处理器,同时修改Action的type属性为Spring容器中bean的ID(不再是全类名):

<struts-config>
    <!-- 启用Spring请求处理器,让Spring接管Action调用 -->
    <controller>
        <set-property property="processorClass" value="org.springframework.web.struts.SpringRequestProcessor"/>
    </controller>

    <!-- 示例Action配置:type对应Spring中bean的id -->
    <action-mappings>
        <action path="/user/save" type="userSaveAction" name="userForm" scope="request">
            <forward name="success" path="/user/list.do"/>
        </action>
    </action-mappings>
</struts-config>

1.3 配置applicationContext.xml

开启组件扫描、AOP自动代理,并注册Action和业务类的bean:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 扫描业务层、Action包,自动注册带有@Component/@Service/@Controller注解的类 -->
    <context:component-scan base-package="com.yourcompany.service, com.yourcompany.action"/>

    <!-- 开启AspectJ注解驱动的AOP自动代理 -->
    <aop:aspectj-autoproxy/>

    <!-- 示例Action bean(如果不用@Component注解,就手动注册) -->
    <bean id="userSaveAction" class="com.yourcompany.action.UserSaveAction">
        <property name="userService" ref="userService"/>
    </bean>

    <!-- 示例业务层bean -->
    <bean id="userService" class="com.yourcompany.service.impl.UserServiceImpl"/>
</beans>
第二步:实现AspectJ审计切面

编写一个切面类,用注解定义切点和通知,完全无侵入式拦截方法调用:

package com.yourcompany.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Date;

@Aspect
@Component // 让Spring扫描并管理这个切面类
public class AuditAspect {

    // 定义切点:拦截业务层所有方法(可根据需求调整表达式)
    @Pointcut("execution(* com.yourcompany.service.*.*(..))")
    public void serviceMethodPointcut() {}

    // 后置通知:方法执行成功后记录审计日志
    @AfterReturning(pointcut = "serviceMethodPointcut()", returning = "result")
    public void logSuccessAudit(JoinPoint joinPoint, Object result) {
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        Object[] params = joinPoint.getArgs();

        // 这里替换为你的实际审计逻辑:比如写入数据库、调用日志服务等
        System.out.println(String.format("[%s] 审计记录:类%s的方法%s执行成功,参数:%s,返回结果:%s",
                new Date(), className, methodName, params, result));
    }

    // 异常通知:方法抛出异常时记录错误审计
    @AfterReturning(pointcut = "serviceMethodPointcut()", throwing = "ex")
    public void logErrorAudit(JoinPoint joinPoint, Exception ex) {
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();

        System.out.println(String.format("[%s] 错误审计记录:类%s的方法%s执行失败,异常信息:%s",
                new Date(), className, methodName, ex.getMessage()));
    }
}

关键说明:@Pointcut的表达式可以灵活调整,比如只拦截save/update开头的方法:execution(* com.yourcompany.service.*.save*(..)),或者拦截带有自定义@Audit注解的方法。

第三步:准备依赖包

如果用Maven,确保引入以下核心依赖(版本可根据项目兼容性调整):

<!-- Spring核心依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
</dependency>

<!-- Struts1与Spring整合依赖 -->
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts-core</artifactId>
    <version>1.3.10</version>
</dependency>
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts-spring</artifactId>
    <version>1.3.10</version>
</dependency>

关键说明:struts-spring是Struts1和Spring整合的桥梁,必须引入,它提供了我们之前用到的DelegatingActionProxy等类。

注意事项
  • 确保所有需要被AOP拦截的类(业务类、Action)都由Spring管理,要么用注解,要么手动注册到applicationContext.xml。
  • 如果需要拦截Struts的Action方法,只需要调整@Pointcut的表达式,比如execution(* com.yourcompany.action.*.*(..))。
  • 审计日志的实现建议异步处理,避免影响主业务流程,比如用Spring的@Async注解或者消息队列。

内容的提问来源于stack exchange,提问作者KESO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:47:24