您的位置:首页 > 编程语言 > ASP

@Aspect @around 多个参数

2016-01-05 17:12 1016 查看
摘要: 之前参考了网友的代码,aop可以指定入参方便编码。但是有些地方还是不太懂,请大神指点迷津
controller 推荐使用拦截器extends org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

直接上代码:

@Aspect
@Component
public class LogErrorAspect {

private static final Logger LOGGER = LoggerFactory.getLogger(LogErrorAspect.class);

private static final String NB = "nb";

@Pointcut(value = "within(com.aop.service.order..*) && @annotation(com.aop.intf.dto.order.EasyValid)")

public void logErrorPointCut(){

}
/*

异常拦截加参数e

@AfterThrowing(value="within(com.aop.ysma..*)", throwing="e")

可行方案:能拦截到service层代码,但是如此书写却是拦截不到controller的
@Around("within(com.aop.service.order..*) && @annotation(easyValid)")
可行方案:能拦截到service和controller层代码 两个参数
@Around(value = "execution(@com.aop.service.order * *(..)) && @annotation(easyValid)")
可行方案:能拦截到service和controller层代码

@Around("within(com.ysma.aop..*) && @annotation(com.ysma.aop.intf.base.db.ReadOnly)")
可行方案

@Around("@annotation(com.aop.service.order.EasyValid)")
public Object aroundSimple(ProceedingJoinPoint pj, EasyValid easyValid) throws Throwable {
LOGGER.debug("diy aroundSimple =================");
return pj.proceed();
}*/

/**不可行方案

@Around(value = "logErrorPointCut() && args(com.aop.intf.dto.order.EasyValid)", argNames = "pj, easyValid")

*/
@Around(value = "logErrorPointCut() && args(easyValid)", argNames = "pj, easyValid")
public Object around(ProceedingJoinPoint pj, EasyValid easyValid) throws Throwable {
/*@Around("logErrorPointCut()")
public Object around(ProceedingJoinPoint pj) throws Throwable {*/
//pj.getClass().getAnnotation(EasyValid.class);
LOGGER.debug("diy operation =================");
if(easyValid == null){
LOGGER.debug("easyValid is null =================");
return pj.proceed();
}
boolean nb = NB.equals(easyValid.source());

return pj.proceed();
}

}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EasyValid {

/**
* b/g 必须输入
* @return
*/
String source();

/**
* 入参 必须输入
* @return
*/
String operatiton() default "";
}

注:被注解的方法须是public方法 protect和private方法虽不会报错却也不会生效

那么问题来了:采用不可行方案将pointcut和advice拆分开来我的切面就拦截不到标记了annotation的服务;

采用可行方案将pointcut和advice不拆分,就能正常获取参数并拦截标记了annotation的服务;

备注:1、我跟踪了一下spring的源码,发现采用不可行的方案时,spring只会取其中的easyValid参数并匹配并且成功匹配到了也能将对应的标记了@EasyValid的服务作为cancaditate加入候选者列表等待匹配调用。
但是临门一脚的时候就跳过了我的LogErrorAspect切面了。

2、我将pj做为参数放入到args里面也会报错。说没有匹配类型的参数。是因为ProceedingJoinPoint是JoinPoint的子类的缘故么?貌似这么理解也不太科学

猜想:是不是代理类proxy在invocation的时候发现参数数目不匹配跳过了不可行方案的方法?

3、之前有看过文章说 controller并不在spring管理范围内,service在spring管理范围内。 所以service走spring代理,aop切面都能切中,但是controller就切不中
此处提供了另类的方式切中controller的aop方式

求教:pointcut和advice拆分的情况下如何定义除pj以外的参数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: