我定义了controller层的aop,以及service等的aop,但是service层的不生效?我用Test类直接getBean,调用userService.xx(),service层aop生效,但是在web项目中就是不生效。我初步猜测是配置或者说加载顺序问题?
新的补充:
反复测试发现,当quartz与shiro同时使用时,service层的aop就会失效。目前不是太过确定原因,但是一种猜测是shiro自带的quartz与quartz.jar冲突导致的。但是问题来了,为什么他们冲突导致service层的aop失效呢?而controller层不失效?
package com.yingjun.ssm.aop;
import com.yingjun.ssm.dto.BaseResult;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
/**
*
* 采用AOP的方式处理@Valid 参数验证。
*/
@Component
@Aspect
public class BindingResultAop {
private static final Logger LOG = LoggerFactory.getLogger(BindingResultAop.class);
@Pointcut("execution(* com.yingjun.ssm.web.*.*(..))")
public void bindingResultPointcut(){
//该方法的内容不重要,该方法的本身只是个标识,供@Pointcut注解依附
}
/**
* Aspect = Advice + Pointcut
* Advice: @Around
* Pointcut: execution(* com.yingjun.ssm.web.*.*(..))
*/
@Around("bindingResultPointcut()")
public Object aroundAdvice(ProceedingJoinPoint jp) throws Throwable{
System.out.println("--->BindingResultAop start...");
String className = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
LOG.info("before " + className + "." + methodName + "() invoking!");
// 遍历参数,找到BindingResult,判断是否hasError
BindingResult bindingResult = null;
for(Object arg: jp.getArgs()){
if(arg instanceof BindingResult){
bindingResult = (BindingResult) arg;
}
}
if(bindingResult != null){
if(bindingResult.hasErrors()){
LOG.info("--->bindingResult hasError!");
String errorInfo="["+bindingResult.getFieldError().getField()+"]"+bindingResult.getFieldError().getDefaultMessage();
return new BaseResult
package com.yingjun.ssm.aop;
import com.yingjun.ssm.cache.RedisCache;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.asm.AnnotationVisitor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
*
* 采用AOP的方式处理: XXService关于数据更新(增删改)时,缓存的清理。
*/
@Component
@Aspect
public class ClearCacheAop {
private static final Logger LOG = LoggerFactory.getLogger(ClearCacheAop.class);
private static final String[] UPDATE_USER_MOTHOD = new String[]{"createUser", "updateUser", "deleteUser", "changePassword"};
private static final String[] UPDATE_ROLE_MOTHOD = new String[]{"createRole", "updateRole", "deleteRole"};
private static final String[] UPDATE_RESOURCE_MOTHOD = new String[]{"createResource", "updateResource", "deleteResource"};
@Autowired
private RedisCache cache;
// 声明切入点
@Pointcut("execution(* com.yingjun.ssm.service..*.*(..))")
public void clearCachePointcut(){}
@Before("clearCachePointcut()")
public void beforeAdvice(JoinPoint jp) {
System.out.println("--->clearCachePointcut start...");
String className = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
LOG.info("before " + className + "." + methodName + "() invoking!");
if(StringUtils.contains(className, "UserService") && ArrayUtils.contains(UPDATE_USER_MOTHOD, methodName)){
// 此时缓存中的数据不是最新的,需要对缓存进行清理(具体的缓存策略还是要根据具体需求制定)
String cache_key = RedisCache.CAHCENAME + "|UserService|*";
cache.deleteCacheWithPattern(cache_key);
LOG.info("aop: delete cache with key: " + cache_key);
} else if(StringUtils.contains(className, "RoleService") && ArrayUtils.contains(UPDATE_ROLE_MOTHOD, methodName)){
String cache_key = RedisCache.CAHCENAME + "|RoleService|*";
cache.deleteCacheWithPattern(cache_key);
LOG.info("aop: delete cache with key: " + cache_key);
} else if(StringUtils.contains(className, "ResourceService") && ArrayUtils.contains(UPDATE_RESOURCE_MOTHOD, methodName)){
String cache_key = RedisCache.CAHCENAME + "|ResourceService|*";
cache.deleteCacheWithPattern(cache_key);
LOG.info("aop: delete cache with key: " + cache_key);
}
}
}
/static/** = anon
/welcome = anon
/login = authc
/register = anon
/logout = logout
/authenticated = authc
/** = user
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
应该是spring容器扫描范围的问题
<!-- 激活组件扫描功能,扫描aop的相关组件组件 -->
你在service.xml 里面加这句话试试
补充内容:另外一个配置文件去掉对应的内容
反复测试发现,当quartz与shiro同时使用时,service层的aop就会失效。目前不是太过确定原因,但是一种猜测是shiro自带的quartz与quartz.jar冲突导致的。但是问题来了,为什么他们冲突导致service层的aop失效呢?而controller层不失效?