【问题标题】:Spring AOP setAdvice only on one specific MethodSpring AOP setAdvice 仅针对一种特定方法
【发布时间】:2011-11-27 23:51:13
【问题描述】:

我有以下课程:

package x.y.z;

public class MyClass{
public void someMethod(SomeObject object){
//do somethinng
}

public void {
//do somethinng
}

}

现在我想在方法someMethod(SomeObject object, int param1)上设置@PointCutonly

我该怎么做?

更新我正在尝试

@Pointcut("execution(x.y.z.MyClass.someMethod(x.y.z.SomeObject))") but I'm getting not well formed pointcut exception.

【问题讨论】:

  • 你不能让切入点明确地命名该方法而不是使用通配符吗?
  • @Dave,我该怎么做?这正是我的问题

标签: java spring jakarta-ee aop spring-aop


【解决方案1】:

切入点应该是:

target(x.y.z.MyClass) && execution(<RETURN TYPE> someMethod(x.y.z.SomeObject))

【讨论】:

    【解决方案2】:

    将 AspectJ 附加到您的类路径并使用 maven AOP 插件将此 Aspect 编译为字节码,看看这个例子:

    @Aspect
    public class IOControlAspect {
        @Around("execution(com...SomeClass.someMethod(*))")
        public Object ioControlWrapper(ProceedingJoinPoint thisJoinPoint) throws Throwable {
            {your code here}
            return thisJoinPoint.proceed();
        }
    }
    

    【讨论】:

    • 很好,但是它将执行哪些方法我有相同名称和不同参数的方法。
    • 没关系,可以使用execution(com...SomeClass.someMethod(int, java.lang.String, etc.))来指定参数
    • 我不记得 Spring AOP 是否支持这种表示法,但 AspectJ 可以使用它。
    • 如果您使用return pjp.proceed();,那么您最好使用@Before 建议和更简单的方法。 (我更喜欢使用注解来标记被拦截的方法,但是这样对被拦截的代码的侵入性更大。)
    【解决方案3】:

    假设我们有一个@Controller 类:

    package co.gg.controller;
    
    @Controller
    public class LoginController {
    
        @GetMapping(value="/getTenantRoles")
        @ResponseBody
        public String getTenantRoles(@RequestParam("tenant_id") String tenant_id) throws SQLException {
    
            sqlConnection = con.makeconnection(dbName, dbPort, dbUserName, dbPass, dbHost);
    
            String sql = "select * from tenant_role where tenant_id = "+tenant_id+" and is_active = 1 and is_deleted = 0;";
            PreparedStatement preparedStatement = sqlConnection.prepareStatement(sql);
            ResultSet rs = preparedStatement.executeQuery();
    
            ArrayList<TenantRoleModel> tenantRoleModelList = new ArrayList<>();
            while(rs.next()) {
                TenantRoleModel currentModel = new TenantRoleModel(
                                                                        rs.getInt("tenant_role_id"),
                                                                        rs.getInt("is_deleted"),
                                                                        rs.getInt("is_active"),
                                                                        rs.getInt("tenant_id"),
                                                                        rs.getString("role_name"),
                                                                        rs.getString("create_date")
                                                                    );
    
                tenantRoleModelList.add(currentModel);
            }
    
            return new Gson().toJson(tenantRoleModelList);
        }
    }
    

    那么我们必须像这样拦截那个方法:

    package co.gg.AOP;
    
    
    @Aspect
    @Component
    @EnableAspectJAutoProxy(proxyTargetClass=true)
    public class Aspects {
    
        @AfterReturning(value = "execution(* co.fdbk.controller.LoginController.getTenantRoles(..))", returning = "result")
        public void afterAPICall(JoinPoint joinPoint,Object result){
    
            System.out.println("AOP Method Name :"+ joinPoint.getSignature().getName());
            System.out.println("AOP Return Value  :"+ result);
    
    
        }
    }
    

    这就是我们可以拦截特定方法的方式。

    【讨论】:

      猜你喜欢
      • 2014-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多