之前已经使用注释语法对此进行了回答:Aspectj覆盖方法的参数
但我无法弄清楚如何使用AspectJ声明语法来实现它.以下应该在方法中的每个字符串前添加"Poop",但事实并非如此.
public aspect UserInputSanitizerAdvisor {
pointcut unSafeString() : execution(@RequestMapping * * (..));
Object around() : unSafeString() {
//thisJoinPoint.getArgs();
//proceed();
System.out.println("I'm Around");
Object[] args = thisJoinPoint.getArgs();
if (args != null) {
for (int i = 0; i < args.length; i++) {
Object o = args[i];
if (o != null && o instanceof String) {
String s = (String) o;
args[i] = "poop: " + s;
}
}
}
return proceed();
}
}
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何给出"proceed()"所有的论点.
从以下上一个问题(AspectJ - 无法识别连接点表达式中的注释的存在),
我的目标:在一个方面,我希望能够从匹配函数中提取/检索所有带注释的参数,无论有多少.(然后应用一些处理,但这不是这个问题的范围)
所以目前,这就是我所做的(不工作):
@Before("execution (* org.xx.xx.xx..*.*(@org.xx.xx.xx.xx.xx.Standardized (*),..))")
public void standardize(JoinPoint jp) throws Throwable {
Object[] myArgs = jp.getArgs();
getLogger().info("Here: arg length=" + myArgs.length);
// Roll on join point arguments
for (Object myParam : myArgs) {
getLogger().info(
"In argument with " + myParam.getClass().getAnnotations().length
+ " declaread annotations");
getLogger().info("Class name is " + myParam.getClass().getName());
// Get only the one matching the expected @Standardized annotation
if (myParam.getClass().getAnnotation(Standardized.class) != null) {
getLogger().info("Found parameter annotated with @Standardized");
standardizeData(myParam.getClass().getAnnotation(Standardized.class), myParam);
}
} …Run Code Online (Sandbox Code Playgroud) 我对AOP完全不熟悉.我需要建议写出正确的切入点.我有一个包含所有服务类的服务包.所有类都实现了Service接口.该接口有一个方法save(entity).每次service.save(entity)方法抛出时我都应该执行我的建议DataIntegrityViolationException.
这方面:
@Component
@Aspect
public class DIVExceptionHandler {
@AfterThrowing(pointcut = "execution(* myPackage.service.Service.save(*))", throwing = "ex")
public void handleException(JoinPoint joinPoint, DataIntegrityViolationException ex) {
//snipped
}
}
Run Code Online (Sandbox Code Playgroud)
我在CP中有两个aspectj jar,如Spring AOP文档中所述,我已经添加<aop:aspectj-autoproxy/>到Spring配置中,我正在使用组件扫描.在测试的日志中,我可以看到方面被检测为aspetcj方面:
DEBUG o.s.a.a.a.ReflectiveAspectJAdvisorFactory - Found AspectJ method...
Run Code Online (Sandbox Code Playgroud)
所以我认为这不是一个配置问题,我的切入点表达是错误的.我也试过了
@AfterThrowing(pointcut = "execution(* myPackage.service.*.save(*))", throwing = "ex")
Run Code Online (Sandbox Code Playgroud)
但这也行不通.
那么正确的切入点表达是什么?
在我的web.xml文件中,我有:
Run Code Online (Sandbox Code Playgroud)<!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>contextConfigLocation类路径:shared-context.xml
Run Code Online (Sandbox Code Playgroud)<!-- Main general mapping, i.e. context for the UI & version queries --> <servlet> <servlet-name>mainDispacherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:web-application-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mainDispacherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- Processes application requests for version 1 --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:version-api-contexts/application-context[v1.0].xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/api/v1.0/*</url-pattern> </servlet-mapping>
在父上下文中shared-context.xml,我有:
<aop:aspectj-autoproxy/>
<context:component-scan base-package="com.company.cse.support.audit"/>
Run Code Online (Sandbox Code Playgroud)
该包com.company.cse.support.audit包含一个标有@Component和@Aspect的类.此方面将消息记录到我的审核日志中.
当我在子上下文中定义的bean上调用一个方法时version-api-contexts/application-context[v1.0].xml,bean不会被spring AOP代理,并且不会调用该方面.如果我将方面定义行移动<context:component-scan base-package="com.company.cse.support.audit"/>
到子上下文XML,则方面可以正常工作. …
我正在从Spring 2.5.6迁移到3.2.5.jar spring-aspects-3.2.5包含新方面JpaExceptionTranslatorAspect,它将标准JPA异常转换为Spring异常.它似乎是一个特定于Roo的方面.这个方面会自动编织到存储库中(使用@Repository注释).因此,标准JPA异常不再被捕获并且应用程序被破坏.
如何排除JpaExceptionTranslatorAspect被编织?如果无法完成,还有其他解决方法吗?或者我错过了一些配置?
我正在使用AspectJ 1.7.4和AspectJ Maven插件1.4.
我已经收集了什么:
但是,我想知道这些信息是否是最新的.
我能够根据我的基本需求获得@annotation切入点.
@Pointcut ("@annotation(path.to.my.CustomAnnotation)")
public void actionAnnotatedPointCut() {}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试将它绑定到下面的建议体时,我得到了IllegalArgumentException.
@Pointcut ("@annotation(customAnnotation)")
public void actionAnnotatedPointCut(CustomAnnotation customAnnotation) {}
Run Code Online (Sandbox Code Playgroud)
例外:
Caused by: java.lang.IllegalArgumentException: error at ::0 incompatible number of arguments to pointcut, expected 1 found 0
Run Code Online (Sandbox Code Playgroud)
完整跟踪:
Jan 29, 2014 9:45:29 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
Jan 29, 2014 9:45:29 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.annotation.internalPersistenceAnnotationProcessor': Initialization of bean failed; nested exception is …Run Code Online (Sandbox Code Playgroud) 看看这个Eclipse Bug似乎Java Verifier(自1.6起)与ApsectJ存在问题.
错误说AspectJ 1.8.1将解决问题.但是在Java8u11中使用它仍然会得到验证错误.
我在STS 3.6.0(Eclipse 4.4)下运行JUnit4.我相信这个配置是所有软件包中最新的.
用请求的示例完全替换了剩下的文本.这似乎仅限于@Around建议. @Before工作正常.
JUnit的:
package com.test.aspectjdemo.junit;
import static org.junit.Assert.*;
import org.junit.Test;
import com.test.aspectjdemo.domain.AspectTarget;
public class AspectTargetTest {
@Test
public void testFirstMethod() throws Throwable {
AspectTarget aspectTarget = new AspectTarget();
aspectTarget.firstMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
Vmarg:-javaagent:C:.... m2\repository\org\aspectj\aspectjweaver\1.8.1\aspectjweaver-1.8.1.jar
正在测试的类(我有一些问题,因为显然声明它抛出Throwable,这是有道理的,但这个简单的测试没有抛出任何东西.所以我添加了一个虚假的异常使它编译:
package com.test.aspectjdemo.domain;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class AspectTarget {
final Logger logger = LogManager.getLogger();
int x = 1;
public void firstMethod() throws Throwable {
logger.info("Start First Method");
x = secondMethod(x);
logger.info("Exit X is {}", x); …Run Code Online (Sandbox Code Playgroud) 我正在使用AspectJ使用我的自定义注释进行切入点的奇怪行为.
我使用的切入点是:
@AfterThrowing(pointcut="@annotation(com.core.meta.NotifyOnFailure)", throwing="ex")
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我的方面执行了两次,但如果我将切入点修改为:
@AfterThrowing(pointcut="execution(* sendAndReceive(..))", throwing="ex")
Run Code Online (Sandbox Code Playgroud)
它按预期运行一次.
我提出方面的唯一方法是:
@NotifyOnFailure // I want to use this annotation to raise the aspect once
public String sendAndReceive(String serviceUrl)
{
String responseXml = "...";
try
{
throw new Exception("test...");
}
catch(Exception x)
{
ExternalExecutionException ex = new ExternalApiExecutionException("Service failed");
throw ex;
}
finally
{
...
}
return responseXml;
}
Run Code Online (Sandbox Code Playgroud)
任何关于为什么我的方面在使用我的自定义注释时执行两次而在使用execution切入点时只执行一次的想法?
据我了解,这两个框架都是静态的,可将监视代码注入类代码。那么区别是什么呢?
我正在尝试在发生某些特定异常时添加一些监控.例如,如果我有这样的方面:
@Aspect
public class LogAspect {
@AfterThrowing(value = "execution(* *(..))", throwing = "e")
public void log(JoinPoint joinPoint, Throwable e){
System.out.println("Some logging stuff");
}
}
Run Code Online (Sandbox Code Playgroud)
和测试类:
public class Example {
public void divideByZeroWithCatch(){
try{
int a = 5/0;
}
catch (ArithmeticException e){
System.out.println("Can not divide by zero");
}
}
public void divideByZeroWithNoCatch(){
int b = 5/0;
}
public static void main (String [] args){
Example e = new Example();
System.out.println("***** Calling method with catch block *****");
e.divideByZeroWithCatch();
System.out.println("***** Calling method without …Run Code Online (Sandbox Code Playgroud)