简体   繁体   English

需要在纯Java(ee,servlet和POJO)中创建方法拦截器以在weblogic中使用,该怎么做?

[英]In need to create method interceptors in plain java (ee, servlets and POJOs) to use in weblogic, what can I use to do so?

I'm implementing an audit api to log any method invocation which has an @Auditable annotation in its declaration. 我正在实现一个审核API,以记录其声明中具有@Auditable批注的任何方法调用。 The basic requirements are that it must be used by current applications and should be non-intrusive. 基本要求是当前应用程序必须使用它,并且它应该是非侵入性的。 I already have the auditing API by means of a Log4J2 wrapper, and also I successfully used it in some EJB Interceptors. 我已经通过Log4J2包装器获得了审核API,并且在某些EJB拦截器中也成功使用了它。 However, I need to create an all-terrain interceptor I can use wherever the annotation is used, ie, I'd like to annotate servlets, EJBs and POJOs methods with it and let the interceptor work its magic. 但是,我需要创建一个全地形的拦截器,无论在何处使用注释,都可以使用它,即,我想用它来注释servlet,EJB和POJO方法,并让拦截器发挥其魔力。

I've tried Java EE Interceptors and they only work in EJB, I've tried GUICE but it doesn't work with servlet nor EJB methods, only guice injected POJOs. 我已经尝试过Java EE拦截器,它们仅在EJB中工作,我已经尝试过GUICE,但是它不适用于servlet或EJB方法,只能用于注入guice的POJO。

I'd like to know, if somebody knows how, what should I use and I'll be gratefull if an example can be pointed at to. 我想知道,如果有人知道如何使用,我将不胜感激,如果可以举一个例子。

Thank you very much. 非常感谢你。

One possible solution is using AspectJ. 一种可能的解决方案是使用AspectJ。 AspectJ can let you define what you want to intercept (the so called joinpoint) and execute the code you want (the so called advice) when it happens. AspectJ可以让您定义要拦截的内容(所谓的联接点),并在发生时执行想要的代码(所谓的建议)。

Joinpoints can be everything, but in your case you need to trap the execution of methods with a given annotation, so we will be using only the "execution" joinpoint. 连接点可以是所有东西,但是在您的情况下,您需要使用给定的注释来捕获方法的执行,因此我们将仅使用“执行”连接点。

AspectJ then needs to instrument your classes. 然后,AspectJ需要对您的类进行检测。 This can be done : 这可以做到:

  1. Compiling your code with the AspectJ compiler, which extends the java compiler with what needed 使用AspectJ编译器来编译代码,这可以扩展Java编译器的需求
  2. "Weaving" existing jar files, so you can do it after the normal build process, or you can do it even on jar files you don't have the sources (which is not in this case, since you need to place the annotation anyway). “编织”现有的jar文件,因此您可以在正常的构建过程之后执行此操作,或者甚至可以在没有源的jar文件上执行此操作(在这种情况下,因为您仍然需要放置注释)。

We will use the first method only to compile the aspect, and the second one to instrument the jar files or class folders you want. 我们将仅使用第一种方法来编译方面,第二种方法来检测所需的jar文件或类文件夹。

To do it, you need to write an annotation, Auditable, that must have runtime retention. 为此,您需要编写一个注释,它必须具有运行时保留性,为Auditable。

Then you write an aspect : 然后,您编写一个方面:

public aspect Audit {  // An aspect then compiles as if it was a class (at runtime, it is a normal class)

  Object around() :  // This is an around advice
    execution(@Auditable * *(..)) // Here you're catching execution of any method of any class with any parameter and any return type, which is annotated with @Auditable
  {
    // Do what you want to do before the method
    long start = System.nanoTime();
    Logger.log("I'm entering into " + thisJoinPoint); // with thisJoinPoint you can extract a lot of informations, like what class, what method, what parameters, on which instance etc..
    try {
      Object ret = proceed(); // "proceed" goes on executing the method
      // You could log, or do whatever you want with the return value, which could be "Void".
      return ret;
    } finally {
      Logger.log("It took ns: " + (System.nanoTime() - start));
    }
  }

}

Once you wrote this aspect (usually in a package and with a ".aj" extension, but is not mandatory), you compile it with the AspectJ compiler. 一旦编写了此方面(通常在软件包中,并带有“ .aj”扩展名,但不是强制性的),就可以使用AspectJ编译器对其进行编译。

ajc -outxml -classpath thisLib.jar:thatLib.jar -1.5 -outjar auditableAspect.jar package/of/your/AuditableAspect.aj 

This is similar to compiling java code with javac. 这类似于使用javac编译Java代码。 On the classpath you need what is needed to compile the aspect, in this example i used a misterious Logger, which must be inside thisLis.jar or thatLib.jar. 在类路径上,您需要编译方面的内容,在本示例中,我使用了错误的Logger,该Logger必须位于thisLis.jar或thatLib.jar中。

At the end, you'll have an auditableAspect.jar file, that will contain the compiled class of you aspect. 最后,您将拥有一个auditableAspect.jar文件,其中将包含您方面的已编译类。

Now, to use it, you need to "weave" the classes (or jar files) you want it to "intercept". 现在,要使用它,您需要“编织”要使其“拦截”的类(或jar文件)。 To do this, still with the ajc command : 为此,仍然使用ajc命令:

ajc -inpath myStuff.jar -outjar myStuffAudited.jar -aspectPath auditableAspect.jar

You'll then find in myStuffAudited.jar the same classes in myStuff.jar, and a few other synthetic inner anonymous classes. 然后,您将在myStuffAudited.jar中找到myStuff.jar中的相同类,以及其他一些合成内部匿名类。

Now basically you can remove from your application classpath (or WEB-INF/lib if it's a web application) the myStuff.jar, replace it with myStuffAudited.jar, and also add auditableAspect.jar which is your aspect and aspectjrt.jar which is AspectJ runtime. 现在,基本上您可以从应用程序类路径(如果是Web应用程序,则从WEB-INF / lib)中删除myStuff.jar,将其替换为myStuffAudited.jar,还添加您的aspectableAspect.jar和aspectjrt.jar。 AspectJ运行时。

Reload you application, and it will start logging. 重新加载您的应用程序,它将开始记录。

You can do this on all the jars you want, or on all jars in a for loop; 您可以在所需的所有jar上或在for循环中的所有jar上执行此操作; those unaffected will remain unaffected. 那些不受影响的人将保持不受影响。

This can be integrated in a number of ways in your build cycle. 在构建周期中,可以通过多种方式将其集成。

  • Obviously, a .bat or .sh script can automate it 显然,.bat或.sh脚本可以使其自动化
  • Ant has tasks for aspectJ 蚂蚁的任务是AspectJ
  • Maven has a plugin for aspectJ Maven有一个AspectJ插件
  • Eclipse has a plugin for compiling and weaving inside the ide Eclipse有一个插件可以在ide中进行编译和编织

Don't know how you build your project, so YMMV. YMMV不知道如何构建项目。

Wether this is intrusive or not, it's an opinion; 无论这是否具有侵入性,这都是一种意见。 but to my knowledge there aren't a lot of packages out there that offer runtime auditing without somehow manipulating the class bytecode, if not using runtime proxies that are limited (as you have seen) to interfaces. 但是据我所知,如果没有使用(如您所见)限于接口的运行时代理,那么没有很多软件包可以提供运行时审计而又不以某种方式操纵类字节码。

There is also an option to use a weaving classloader, that would remove totally the need to weave existing jars and classes, cause they would be weaved at load time by the classloader itself. 还有一个使用编织类加载器的选项,它将完全不需要编织现有的jar和类,因为它们将在加载时由类加载器本身进行编织。 It works great and i like it, but it depends on your runtime environment. 它很棒,我喜欢它,但是它取决于您的运行时环境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM