Java 如何在执行带注释的方法和传递参数之前调用外部方法
我正在从事POJO项目,该项目使用Java 如何在执行带注释的方法和传递参数之前调用外部方法,java,annotations,aop,pojo,Java,Annotations,Aop,Pojo,我正在从事POJO项目,该项目使用Maven构建到一个独立的JAR中。为了可维护性,我正在考虑添加一种使用基于注释的检查的方法。在下面的代码中,我有一个带注释的方法,在调用此方法时,我希望执行另一个类中的另一个方法,并具有上下文意识,以便访问传递给原始方法的参数 public class SomeClass { public static void someClassMethod(){ ... get(new AnotherClass() {
Maven
构建到一个独立的JAR中。为了可维护性,我正在考虑添加一种使用基于注释的检查的方法。在下面的代码中,我有一个带注释的方法,在调用此方法时,我希望执行另一个类中的另一个方法,并具有上下文意识,以便访问传递给原始方法的参数
public class SomeClass {
public static void someClassMethod(){
...
get(new AnotherClass() {
@CustomAnnotation
public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
...
}
});
...
}
}
我知道这可以通过AspectJ实现,但我找不到一个真正的工作示例来说明如何实现这种功能。因此,我想询问一个示例代码,或指向工作示例的链接。我真的无法向您解释AOP基础知识。如果你不愿意至少阅读AOP教程并掌握aspect、joinpoint、pointcut和advice等基本概念,那么在这里要求人们提供示例代码是错误的。我甚至会在AspectJ中为您提供一个功能齐全的示例(见下文),但有什么用呢?你能理解吗?我不打算提供的是Maven配置,因为这实际上超出了范围,即使我知道如何使用Maven构建AspectJ代码。请随意使用搜索引擎学习,然后带着“我懒得学习,请为我做吧”以外的具体问题回来 参数类根据您的示例:
package de.scrum_master.app;
public class ArgumentClass1 {}
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {}
package de.scrum_master.app;
public abstract class AnotherClass {
public abstract Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2);
}
package de.scrum_master.app;
public class SomeClass {
public static void someClassMethod() {
get(new AnotherClass() {
@CustomAnnotation
public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
return "dummy";
}
});
}
public static Object get(AnotherClass anotherClass) {
return anotherClass.handle(new ArgumentClass1(), new ArgumentClass2());
}
private static void anotherClassMethod(String string, String string2) {}
@CustomAnnotation
private static void yetAnotherClassMethod(int i, int j) {}
public static void main(String[] args) {
someClassMethod();
anotherClassMethod("foo", "bar");
yetAnotherClassMethod(11, 22);
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.CustomAnnotation;
public aspect AnnotatedMethodInterceptor {
Object around() : execution(@CustomAnnotation * *(..)) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
System.out.println(" Checking argument " + arg);
}
return proceed();
}
}
--
示例注释:
package de.scrum_master.app;
public class ArgumentClass1 {}
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {}
package de.scrum_master.app;
public abstract class AnotherClass {
public abstract Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2);
}
package de.scrum_master.app;
public class SomeClass {
public static void someClassMethod() {
get(new AnotherClass() {
@CustomAnnotation
public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
return "dummy";
}
});
}
public static Object get(AnotherClass anotherClass) {
return anotherClass.handle(new ArgumentClass1(), new ArgumentClass2());
}
private static void anotherClassMethod(String string, String string2) {}
@CustomAnnotation
private static void yetAnotherClassMethod(int i, int j) {}
public static void main(String[] args) {
someClassMethod();
anotherClassMethod("foo", "bar");
yetAnotherClassMethod(11, 22);
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.CustomAnnotation;
public aspect AnnotatedMethodInterceptor {
Object around() : execution(@CustomAnnotation * *(..)) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
System.out.println(" Checking argument " + arg);
}
return proceed();
}
}
根据您的示例抽象类:
package de.scrum_master.app;
public class ArgumentClass1 {}
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {}
package de.scrum_master.app;
public abstract class AnotherClass {
public abstract Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2);
}
package de.scrum_master.app;
public class SomeClass {
public static void someClassMethod() {
get(new AnotherClass() {
@CustomAnnotation
public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
return "dummy";
}
});
}
public static Object get(AnotherClass anotherClass) {
return anotherClass.handle(new ArgumentClass1(), new ArgumentClass2());
}
private static void anotherClassMethod(String string, String string2) {}
@CustomAnnotation
private static void yetAnotherClassMethod(int i, int j) {}
public static void main(String[] args) {
someClassMethod();
anotherClassMethod("foo", "bar");
yetAnotherClassMethod(11, 22);
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.CustomAnnotation;
public aspect AnnotatedMethodInterceptor {
Object around() : execution(@CustomAnnotation * *(..)) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
System.out.println(" Checking argument " + arg);
}
return proceed();
}
}
带有一些示例方法的应用程序类:
package de.scrum_master.app;
public class ArgumentClass1 {}
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {}
package de.scrum_master.app;
public abstract class AnotherClass {
public abstract Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2);
}
package de.scrum_master.app;
public class SomeClass {
public static void someClassMethod() {
get(new AnotherClass() {
@CustomAnnotation
public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
return "dummy";
}
});
}
public static Object get(AnotherClass anotherClass) {
return anotherClass.handle(new ArgumentClass1(), new ArgumentClass2());
}
private static void anotherClassMethod(String string, String string2) {}
@CustomAnnotation
private static void yetAnotherClassMethod(int i, int j) {}
public static void main(String[] args) {
someClassMethod();
anotherClassMethod("foo", "bar");
yetAnotherClassMethod(11, 22);
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.CustomAnnotation;
public aspect AnnotatedMethodInterceptor {
Object around() : execution(@CustomAnnotation * *(..)) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
System.out.println(" Checking argument " + arg);
}
return proceed();
}
}
如您所见,有一些静态方法,部分是public/private,其中一个由@CustomAnnotation
注释,另一个不是,一个包含一个匿名类,具体化了上面的抽象类,还包含一个由@CustomAnnotation
注释的方法。我们应该期望yetAnotherClassMethod(int,int)
和handle(ArgumentClass1,ArgumentClass2)
被方面截获,因为它们带有我们的目标注释
最后,但并非最不重要的是
带有自定义注释的方面拦截方法:
package de.scrum_master.app;
public class ArgumentClass1 {}
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {}
package de.scrum_master.app;
public abstract class AnotherClass {
public abstract Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2);
}
package de.scrum_master.app;
public class SomeClass {
public static void someClassMethod() {
get(new AnotherClass() {
@CustomAnnotation
public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
return "dummy";
}
});
}
public static Object get(AnotherClass anotherClass) {
return anotherClass.handle(new ArgumentClass1(), new ArgumentClass2());
}
private static void anotherClassMethod(String string, String string2) {}
@CustomAnnotation
private static void yetAnotherClassMethod(int i, int j) {}
public static void main(String[] args) {
someClassMethod();
anotherClassMethod("foo", "bar");
yetAnotherClassMethod(11, 22);
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.CustomAnnotation;
public aspect AnnotatedMethodInterceptor {
Object around() : execution(@CustomAnnotation * *(..)) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
System.out.println(" Checking argument " + arg);
}
return proceed();
}
}
我没有检查示例中的参数,而是在参数数组上循环以打印它们。不过,你可以在这里做任何你想做的事
现在请弄清楚AOP和AspectJ语法都是关于什么的。有足够的教程,只要使用你最喜欢的搜索引擎或从开始
示例代码控制台输出:
package de.scrum_master.app;
public class ArgumentClass1 {}
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {}
package de.scrum_master.app;
public abstract class AnotherClass {
public abstract Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2);
}
package de.scrum_master.app;
public class SomeClass {
public static void someClassMethod() {
get(new AnotherClass() {
@CustomAnnotation
public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
return "dummy";
}
});
}
public static Object get(AnotherClass anotherClass) {
return anotherClass.handle(new ArgumentClass1(), new ArgumentClass2());
}
private static void anotherClassMethod(String string, String string2) {}
@CustomAnnotation
private static void yetAnotherClassMethod(int i, int j) {}
public static void main(String[] args) {
someClassMethod();
anotherClassMethod("foo", "bar");
yetAnotherClassMethod(11, 22);
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.CustomAnnotation;
public aspect AnnotatedMethodInterceptor {
Object around() : execution(@CustomAnnotation * *(..)) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
System.out.println(" Checking argument " + arg);
}
return proceed();
}
}
执行(Object de.scrum\u master.app.SomeClass.1.handle(ArgumentClass1,ArgumentClass2))
正在检查参数de.scrum\u master.app。ArgumentClass1@1bdf2b92
正在检查参数de.scrum\u master.app。ArgumentClass2@58a58c89
执行(void de.scrum_master.app.SomeClass.yetAnotherClassMethod(int,int))
核对论点11
核对论据22
你是在找一个好朋友吗?@John,也许是的,因为我对术语不太熟悉。我看了你所指的页面,但我看不到任何关于什么是切入点以及如何准确实现切入点的解释。我正在寻找一种最简单的方法来做我想做的事情——在执行调用的方法之前执行一些检查。对我来说,注释似乎是一种方式,但我能找到的所有教程都是针对那些已经有相当好的知识的人,而不是完全的新手(我做了很多POJO,从来没有做过AOP)。虽然这个答案可能有用,但它“有点”自大。你自己不这么认为吗?正如我在问题中所说,我主要来自POJO开发。我在阅读和学习maven和gradle时没有遇到任何困难,因为有很多很好的教程和文档。关于AOP,我能找到的只是一些教程,不是针对那些决定第一次接触它的人,而是针对那些已经熟悉AspectJ的所有术语和官方文档的人。请原谅,这个回答的语气非常傲慢。至于例子——谢谢,我会试试。你可以跳过引号,我承认我的答案很自负。那又怎么样?我的批评是实质性的,我的回答也是建设性的。没有好的AOP教程是不正确的。如果您阅读,您将看到它是针对来自POJO开发的绝对初学者的。我自己也是一名POJO开发人员,我从不使用Spring或EJB。我通过阅读教程和其他文档材料自学AspectJ。我还可以推荐Ramnivas Laddad的《AspectJ在行动》一书。祝你好运