gpt4 book ai didi

java - 理解切入点并访问advice中的注释参数

转载 作者:行者123 更新时间:2023-11-30 02:43:25 31 4
gpt4 key购买 nike

有人可以帮我理解aspectj中的以下切入点吗?

这个切入点适用于注释@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")
}

切入点是否正确,无论我在哪里使用 @DynamicValue 注释,它都可以工作吗?

另外我想知道如何访问建议中的注释参数?

最佳答案

注释:

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

顺便说一句,如果您不想更改 get() 的结果,则 @Before 建议就足够了。仅仅打印一些东西 @Around 就太过分了。

<小时/>

因为OP询问是否可以将切入点匹配限制为某种基元类型,例如int,既捕获真实基元又捕获装箱类型Integer,我将展示一个这样做的变体。正如我之前所说,如果不需要操作字段访问器切入点返回的值,则也不需要使用 @Around。我们只使用 @AfterReturning ,因为它有一个可选的 returning 参数,通过该参数我们可以将实际返回值绑定(bind)到通知参数。如果我们为该建议参数选择 Object 之外的其他内容 - 在本例中我们只使用 int - 我们就会得到所要求的内容。

因此,让我们在原始代码中添加两个类型为 intInteger 的带注释参数:

带有注释成员的驱动程序应用程序:

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 字段访问器的修改方面:

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 .

关于java - 理解切入点并访问advice中的注释参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40948302/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com