我有一个方面建议,用于跟踪使用@Service注释的类的执行。代码目前正在运行,但我想更改它以跟踪控制器上的REST端点而不是自动服务。这是代码:
@Aspect
public class AuditingAspect
{
@Pointcut(
//TODO Change pointcut from public methods in Services to REST endpoints in Controllers
"execution(public * my.base.package..*.*(..))" //Must be in package
//+ " && @within(org.springframework.stereotype.Service)" //Has to be a service
+ " && @within(org.springframework.stereotype.Controller)" //Has to be a controller
)
public void auditLoggingPointCut() {
//no op
}
@Around(value ="auditLoggingPointCut()")
public Object logAround(final ProceedingJoinPoint joinPoint) throws Throwable
{
System.out.println("Exection");
returnVal = joinPoint.proceed();
// Now Do The After Logging Part
afterReturningLog(joinPoint, returnVal) ;
return returnVal;
}
private void afterReturningLog(final JoinPoint joinPoint, final Object returnValue)
{
System.out.println("Exiting");
}
}
当我改变""从@Service到@Controller,我没有看到来自建议的任何输出,但是当从URL访问时该方法执行。有什么不同的控制器会忽略执行?
Controller类看起来像这样:
@Controller
public class CaseReferralEndpoints {
@Autowired
CaseReferralFacade caseReferralFacade;
@RequestMapping(value="/backgroundcheck/getcasereferrals", method = RequestMethod.GET)
@ResponseBody
public List<CaseReferralSection> getCaseReferrals(@RequestParam("caseID") Long caseID) {
return caseReferralFacade.getCaseReferrals(caseID);
}
}
这是我的applicationContext-aop.xml完整的配置要大得多,但我相信这是最相关的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="gov.dhs.uscis.elis2.backend.services.logging.AuditingAspect"/>
<aop:aspectj-autoproxy proxy-target-class="false" />
</beans>
答案 0 :(得分:1)
假设您的@within配置正确,可以解决以下问题:
<aop:aspectj-autoproxy proxy-target-class="true" />
此外,您还必须将CGLIB添加到类路径
由于您的控制器未实现接口
,因此需要执行上述步骤最后,如果您有根上下文和Web上下文,则需要将与aop相关的内容应用于Web上下文(在根上下文中将其用于Web上下文中配置的控制器)
<强>更新强>
在Gradle中将CGLIB添加到类路径add:
'cglib:cglib:2.2.2'
在Maven中它将是:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
答案 1 :(得分:0)
正如您的切入点表达式
@within(org.springframework.stereotype.Service)
与&amp;&amp;符号,建议仅适用于您的服务包中。
我希望你的控制器类不在。 .Service包里面,它可能在里面 。*。*控制器包因此不执行控制器
溶液 删除内部切割表达式
或在点切割表达式中添加控制器
答案 2 :(得分:0)
假设您的切入点是正确的,并且您正在使用两个spring上下文,一个用于services / daos(appcontext),另一个用于控制器(servletcontext),我的提示就是错误配置的方向。
AOP配置是仅在声明/扫描的上下文中应用的弹簧bean之一。
因此假设您的控制器有一个servletcontext.xml,除非您在此上下文中声明了aop上下文配置,否则不会应用切入点。
(如果您想将切入点应用于您的服务,则需要申请上下文声明。)
答案 3 :(得分:0)
在applicationContext.xml
中发现了错误我的控制器被过滤掉了上下文扫描!我是该项目的众多开发人员之一,所以我最初并没有想到这里。
<context:component-scan>
<!-- a bunch of packages -->
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
然而,我最终添加了一个已被证明更接近我想要的拦截器。由于我们所有的用户操作都是REST驱动的,因此审计REST调用的调用比尝试和跟踪自动服务的服务方法更容易,更清晰。