6

我想要一个具有拦截所有方法调用的方面的 JAR,例如

@Aspect
public class CoolAspect {
    @Pointcut("execution(public * *(..))")
    public void anyPublicMethod() { }

    @Before("anyPublicMethod()")
    public void advice(JoinPoint point) {
       System.out.println("sign:\t" + point.getSignature());
    }
}

假设以上是我拥有并希望客户使用的方面。我将它编译成 JAR 并提供给 Maven。

现在客户端将使用这个 jar 作为依赖项,例如

    <dependency>
        <groupId>cool-group</groupId>
        <artifactId>cool-artifact</artifactId>
        <version>1.0.0</version>
    </dependency>

该工件 (JAR) 具有上述方面。

现在是否可以通过声明一个 Maven 依赖项来实现方面的工作?

一些可能很重要的事情:

  1. 我打算使用 AspectJ(如果需要,可能是 Spring AOP),
  2. 客户端可能是具有正常web.xml等的 Web 应用程序。
  3. 客户端是用 Maven 构建的
  4. 我希望客户端尽可能易于配置——在我最初的想法中,一个 Maven 依赖项就足够了。
  5. “Annotation JAR”将包含一个网络片段,因此可以在ServletContextListener那里声明一些自定义..

有任何想法吗?

4

2 回答 2

3

如果您使用的是 spring-boot,请为这个问题找到一个简单的解决方案:

在 jar 中,您可以将方面定义为组件:

package com.xxx.yy.zz.aspect;
@Aspect
@Component
public class CoolAspect {
   // code like the question
}

而且,您需要spring.factories/resources/META-INF/. Spring 启动时会扫描这个文件。

和文件spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xxx.yy.zz.aspect.CoolAspect

之后,只需将它们打包成一个罐子。

这将通过声明一个 Maven 依赖项来工作

于 2019-11-06T07:54:39.800 回答
2

不,这是不可能的,因为 AspectJ 必须在任何客户端类之前启动。所有客户端类都应通过特殊的增强类加载器加载,该加载器将处理注释。

另一件事是 Spring 的 AOP。它在应用程序上下文启动期间编织 bean,并且不需要特殊的类加载器。如果客户使用弹簧,那将是最简单的方法。添加maven依赖,然后在应用上下文中配置AOP。

织法有四种:

  • 编译时编织是最简单的方法。当您拥有应用程序的源代码时,ajc 将从源代码编译并生成编织类文件作为输出。weaver 的调用是 ajc 编译过程的组成部分。这些方面本身可以是源代码或二进制形式。如果受影响的类需要这些方面来编译,那么您必须在编译时进行编织。方面是必需的,例如,当它们向类添加成员并且正在编译的其他类引用添加的成员时。
  • 编译后编织(有时也称为二进制编织)用于编织现有的类文件和 JAR 文件。与编译时编织一样,用于编织的方面可以是源形式或二进制形式,并且本身可以由方面编织。
  • 加载时编织 (LTW) 只是延迟到类加载器加载类文件并将类定义到 JVM 的点的二进制编织。为了支持这一点,需要一个或多个“编织类加载器”,由运行时环境显式提供或通过“编织代理”启用。
  • 运行时编织,这实际上是 Spring 正在做的事情。我们将其定义为已经定义的类的编织。到 JVM
于 2013-12-19T11:59:50.983 回答