有人可以帮我理解aspectj中的以下切入点吗?
此切入点适用于注释Set WBook = Workbooks.Open("TestData.xlsm")
,但它的工作方式令人困惑。
以下是我的自定义注释:
@DynamicValue
我的班级使用注释:
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DynamicValue {
String lookupName() default "";
}
包含切入点的方面:
com.package.sample;
Class SampleA{
@DynamicValue("Hello")
public String greet;
//getters & setters
}
切入点是否正确,是否可以在我使用@Aspect
@Configurable
@Component
public class DynamicValueAspect
{
@Pointcut("get(@com.sample.aspect.DynamicValue java.lang.String com.package.sample..*.*)")
public void isDynamicValue() {}
@Around("isDynamicValue()")
public void getLocalized(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Annotation called");
//How can I access the parameter in annotation here
//i.e "Hello" from the @DynamicValue("Hello")
}
注释的任何地方使用?
另外我想知道如何在建议中访问注释参数?
答案 0 :(得分:2)
<强>注释:强>
package de.scrum_master.app;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DynamicValue {
String lookupName() default "";
}
带有注释成员的驱动程序应用程序:
package de.scrum_master.app;
public class Application {
@DynamicValue(lookupName = "foobar")
public String greet;
public String anotherMember;
public static void main(String[] args) {
Application application = new Application();
application.greet = "world";
application.anotherMember = "Another member";
application.sayHello();
}
private void sayHello() {
System.out.println(anotherMember);
System.out.println("Hello " + greet);
}
}
<强>方面:强>
package de.scrum_master.aspect;
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.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;
import de.scrum_master.app.DynamicValue;
@Aspect
@Configurable
@Component
public class DynamicValueAspect {
@Pointcut("get(String de.scrum_master.app..*) && @annotation(dynamicValue)")
public void isDynamicValue(DynamicValue dynamicValue) {}
@Around("isDynamicValue(dynamicValue)")
public Object getLocalized(DynamicValue dynamicValue, ProceedingJoinPoint thisJoinPoint) throws Throwable {
System.out.println(thisJoinPoint);
System.out.println(" " + dynamicValue);
return thisJoinPoint.proceed();
}
}
控制台日志:
Another member
get(String de.scrum_master.app.Application.greet)
@de.scrum_master.app.DynamicValue(lookupName=foobar)
Hello world
顺便说一下,如果您不想更改@Before
的结果,get()
建议就足够了。仅仅打印@Around
的内容有点过分。
因为OP询问是否可以将切入点匹配限制为某个原始类型,如int
,捕获真实基元和盒装类型Integer
,我将展示一个变体。正如我之前所说,如果不需要操作字段访问器切入点返回的值,则也不需要使用@Around
。我们只使用@AfterReturning
因为它有一个可选的returning
参数,通过它我们可以将实际的返回值绑定到一个advice参数。如果那时我们为该建议参数选择Object
以外的其他内容 - 在这种情况下我们只使用int
- 我们得到了所要求的内容。
因此,让我们在原始代码中添加两个带注释的参数int
和Integer
:
带注释成员的驱动程序应用程序:
package de.scrum_master.app;
public class Application {
@DynamicValue(lookupName = "foobar")
public String greet;
public String anotherMember;
@DynamicValue(lookupName = "primitive")
public int primitiveNumber;
@DynamicValue(lookupName = "boxed")
public Integer boxedNumber;
public static void main(String[] args) {
Application application = new Application();
application.greet = "world";
application.anotherMember = "Another member";
application.primitiveNumber = 11;
application.boxedNumber = 22;
application.sayHello();
}
private void sayHello() {
System.out.println(anotherMember);
System.out.println("Hello " + greet);
System.out.println(primitiveNumber);
System.out.println(boxedNumber);
}
}
仅针对int
/ Integer
字段访问者的Mofified方面:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;
import de.scrum_master.app.DynamicValue;
@Aspect
@Configurable
@Component
public class DynamicValueAspect {
@Pointcut("get(* de.scrum_master.app..*) && @annotation(dynamicValue)")
public void isDynamicValue(DynamicValue dynamicValue) {}
@AfterReturning(pointcut = "isDynamicValue(dynamicValue)", returning = "field")
public void getLocalized(DynamicValue dynamicValue, int field, JoinPoint thisJoinPoint) throws Throwable {
System.out.println(thisJoinPoint);
System.out.println(" " + dynamicValue);
}
}
新的控制台日志:
Another member
Hello world
get(int de.scrum_master.app.Application.primitiveNumber)
@de.scrum_master.app.DynamicValue(lookupName=primitive)
11
get(Integer de.scrum_master.app.Application.boxedNumber)
@de.scrum_master.app.DynamicValue(lookupName=boxed)
22
顺便说一下,我回答了类似的问题here。
答案 1 :(得分:0)
按如下方式更改方法签名:
@Around("isDynamicValue()")
public void getLocalized(ProceedingJoinPoint pjp, DynamicValue dynamicValue) throws Throwable {
System.out.println(dynamic.lookupName());
}
如果你的切入点也有问题,我不太明白。这是一个应该可以工作的例子
@Around("execution(@com.package.sample.DynamicValue * *(..)) && @annotation(dynamicValue)")
public void isDynamicValue() {}