@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以外的参数
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以外的参数
相关文章推荐
- 坎坷路:ASP.NET 5 Identity 身份验证(上集)
- Asp.net mvc返回Xml结果,扩展Controller实现XmlResult以返回XML格式数据
- Aspose.word总结
- 对于服务器控件asp:Button单击事件失效问题汇总
- asp.net下应用Echarts饼图
- ASP.NET 用MultiView和View实现选项卡效果
- ASP.NET制作调查问卷
- ASP.NET下载文件到客户端
- ASP调用C的Dll部署服务器出错
- ASP调用C的Dll部署服务器出错
- asp.net页面基类
- ASP.NET 访问共享文件夹
- ASP.NET MVC4 学习记录
- 判断访问asp.net网站是andriod端访问,还是ios,还是pc端访问
- ASP.NET输入文本框自动提示功能
- ASP.NET之AdRotator实现淘宝浏览页面的商品随机推荐功能
- asp.net中实现文件下载功能
- ASP.NET 生命周期
- 创建 ASP.NET Web API的Help Page
- ASP.net ListItem Attributes 属性回传丢失的解决方案