AfterReturning和before,after,around不同是可以获取织入函数的返回值,配置复杂一点。
如果切入点如下:
package com.leanyu.lcsystem.pointcut;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
/**
* @author pandlvs
*描述:切入点定义
*/
@Aspect
public class PointcutsDefinition
{
public static final String ASPECT_SERVICE_EXCUTION = "execution(* com.leanyu.lcsystem.service.*.*(..))";
/**
* 服务层的切入点
*/
@Pointcut(ASPECT_SERVICE_EXCUTION)
public void inServiceLayer(){}
}
则around和AfterReturning的配置区别如下,注意AfterReturning配置必须有argNames参数,且参数值和returning值一样,这样在织入代码里面便可通过returning的值获取被织入函数的返回值。
package com.leanyu.lcsystem.permission.impl;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import com.leanyu.lcsystem.beans.UserBean;
import com.leanyu.lcsystem.permission.ICheckPermission;
import com.leanyu.lcsystem.service.log.SyslogService;
import com.leanyu.rpc.request.AbstractRequest;
import com.leanyu.rpc.response.ObjectResponse;
import com.leanyu.rpc.response.RpcResponse;
/**
* @author pandlvs
*
* 使用@Aspect 注解的类, Spring 将会把它当作一个特殊的Bean(一个切面),也就是
* 不对这个类本身进行动态代理
*/
@Aspect
public class PermissionInterceptor
{
private Logger logger = Logger.getLogger(PermissionInterceptor.class);
@Autowired
private ICheckPermission checkPermission;
@Autowired
private SyslogService syslogService;
/**
* spring中Around通知
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("com.leanyu.lcsystem.pointcut.PointcutsDefinition.inServiceLayer()")
public Object checkPermissionAround( ProceedingJoinPoint joinPoint )
{
try
{
Object[] args = joinPoint.getArgs();
AbstractRequest request = (AbstractRequest)args[0];
int userId = request.getUserId();
String password = request.getPassword();
Signature signature = joinPoint.getSignature();
String service = signature.getDeclaringTypeName();
String method = signature.getName();
if ( checkPermission.hasServicePermission(userId, service , method , password) )
{
Object result = joinPoint.proceed( args );
return result;
}
}catch(Throwable e)
{
logger.error(e.toString(), e);
}
return null;
}
/**
* AfterReturning 三个参数必须有
* @param joinPoint
* @param retVal
*/
@SuppressWarnings("unchecked")
@AfterReturning(value = "com.leanyu.lcsystem.pointcut.PointcutsDefinition.inServiceLayer()",argNames = "retVal",returning = "retVal")
public void logInfo(JoinPoint joinPoint,Object retVal)
{
Object[] object = joinPoint.getArgs();
if(object.length>1) return;
int userId;
if("logout".equals(joinPoint.getSignature().getName()) ||
"login".equals(joinPoint.getSignature().getName())){
if(((ObjectResponse<UserBean>)retVal).getErrorCode()!=0) return;
userId = ((ObjectResponse<UserBean>)retVal).getData().getUserId();
}else{
if("query".equals(joinPoint.getSignature().getName().substring(0, 5))) return;
if(((RpcResponse)retVal).getErrorCode()!=0) return;
userId = ((AbstractRequest)object[0]).getUserId();
}
String action = joinPoint.getSignature().getName();
String service = joinPoint.getSignature().getDeclaringTypeName();
syslogService.addSyslog(userId, action, service);
}
}