我想使用自定义Java注释,使用Spring AOP(和/或AspectJ)在私有类属性中插入一个值。快速示例:
我的注释。java:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface MyAnnotation {
}
MyController.java:
public class MyControllerImpl implements MyController {
...
@MyAnnotation
private String var1;
@Override
public String getVarExample() {
// imagine this is a REST API that gets called on @GET
// request and returns a string
System.out.println(this.var1); // <-- I'd like this to be "helloworld"
// this is just for illustration
// of course, I will want to do
// something more meaningful with
// the 'var1' variable
return "ok"; <- unimportant for this example
}
...
我的方面。java:
@Aspect
@Component
public class MyAspect {
@Pointcut("@annotation(com.mypackage.annotation.MyAnnotation)")
public void fieldAnnotatedWithMyAnnotation() {
}
@Around("fieldAnnotatedWithMyAnnotation()")
public Object enrichVar1(ProceedingJoinPoint pjp) throws Throwable {
// problem #1 - the program never enters here
// problem #2 - I need to figure out how to set up the var1 here
// to "helloworld" , how?
return pjp.proceed();
}
...
}
我将调用并进入getVarExample()
,在它返回后,我希望在控制台或日志中看到“helloworld”。我想使用AOP将var1设置为自定义值。用MyAnnotation注释的任何属性变量都将设置为“helloworld”。我希望上面的例子很清楚。
我确保包名中没有输入错误,还修改了不同的AOP建议注释,如前后的和前后的。我还在MyAnnotation中尝试了不同的目标,最终得到了ElementType。字段应正确。
我知道这是可以做到的,但在网上找不到任何有效的例子。我想再次看到两个答案:
1.如何在MyController入口触发切入点?我想在enrichVar1(..)中捕捉一个断点 MyAspect类的方法。
2.enrichVar1(..)中带注释的值如何修改 MyAspect类的方法?
我不知道我做错了什么。任何帮助都将不胜感激。非常感谢。
AOP在我的项目中设置正确。我知道这一点,因为我已经在为不同的事情使用AOP(例如日志记录)。
更新#1:
请注意,var1
私有变量没有getter或setter。该变量将仅在MyControlllerImpl
中使用。为了更好地说明这一点,我更改了getVarexample
的返回值。
从Spring文档来看,Spring AOP确实支持SpringBeans的方法执行连接点。为了使字段访问连接点工作,您需要使用AspectJ后端和AOP的加载时编织。
但是对于您的情况,不需要使用字段连接点,您可以将注释放在getter上,这应该有效。
正如我在评论中所说:
切入点指示器截取带注释的方法,而不是带注释的字段。为此,本机AspectJ有get()
和set()
。一、 例如,如果迁移到AspectJ,切入点也需要更改。但我同意,在这里,坚持Spring AOP并注释getter方法而不是字段可能就足够了。
但是因为您坚持要保持控制器类不变,所以这里有一个原生的AeyJ解决方案。请阅读将AeyJ与Spring应用程序一起使用一章,了解如何使用@EnableLoadTime编织
和JVM参数-javaagent:/path/to/aspectjweaver.jar
配置它。
为了证明这个解决方案确实独立于Spring工作,我根本没有使用Spring类或注释,只有POJO和原生AspectJ。您可以在Spring应用程序中简单地执行相同的操作。请注意,与Spring AOP方面相比,本机AspectJ方面不需要组件注释。
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface MyAnnotation {}
package de.scrum_master.app;
public interface MyController {
String getVarExample();
}
package de.scrum_master.app;
public class MyControllerImpl implements MyController {
@MyAnnotation
private String var1;
@Override
public String getVarExample() {
System.out.println(this.var1);
return "ok";
}
}
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
MyController myController = new MyControllerImpl();
myController.getVarExample();
}
}
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;
@Aspect
public class MyAspect {
@Pointcut("get(@de.scrum_master.app.MyAnnotation * *)")
public void fieldAnnotatedWithMyAnnotation() {}
@Around("fieldAnnotatedWithMyAnnotation()")
public Object enrichVar1(ProceedingJoinPoint pjp) throws Throwable {
System.out.println(pjp);
return "helloworld";
}
}
运行应用程序时,控制台日志将为:
get(String de.scrum_master.app.MyControllerImpl.var1)
helloworld
AspectJ手册解释了字段获取和设置连接点签名和字段模式的语法。
注意:我认为您的用例可能是黑客攻击,而不是有效的应用程序设计。你应该重构而不是侵入这样的应用程序。
我想根据“配置文件”设置注释的值。 让我举个例子来解释; 在上面的例子中,我们可以看到活动的“配置文件”是PROD,但是假设我们想要使用DEV配置文件,我们将不得不注释来自PROD的@Table注释,并取消注释DEV@Table注释。 如果这只针对一个实体,那不会是一个问题,但我有很多实体都有这种情况,所以我不认为这是处理这种即兴“简介”的方式。 你知道有什么办法可以解决这种情况吗?
例如,我有一个bean类 我想设置这个属性的值。 在Xml配置中,我可以 我如何实现同样的事情,即设置属性的值使用Java注释?现在我已经读到,我们可以使用@Value注释使用一些属性文件,但它不能不使用属性文件,做的方式,我通过xml文件?或者使用属性文件是必要的? 我可以通过包含
问题是我写了简单的注释处理器,它根本不处理类型注释。simple annotations processor的源代码如下所示: 有什么想法如何使用或如何通过SimpleAnnotationsProcessor访问类型注释吗?使用可插入的注释处理API对我来说是不必要的,我认为它会比Java反射有更好的性能。无论如何,我也不知道如何通过Java反射访问类型注释。
我发现了几个与此相关的(不是重复的)问题,但它们不能让我满意。 我无法理解在哪里以及为什么要使用? 我在一本书中读到了一个自定义注释的示例,但没有详细解释。 myMeth()内的输出与预期一致。 关于这个例子,我有几个问题。 1-如何在此程序中使用和?或
我们结合使用JAX-WS和JAXB来接收和解析XML web服务调用。所有这些都是基于注释的,也就是说,我们在代码中从未掌握过JAXBContext。我需要在解组器上设置一个自定义ValidationEventHandler,这样,如果某个特定字段的日期格式不被接受,我们就可以捕获错误并在响应中报告一些好消息。我们在讨论的字段上有一个XMLJavaTypeAdapter,它进行解析并引发异常。我看