繁体   English   中英

在 Spring Boot 中使用本机 AspectJ 拦截嵌套方法

[英]Intercept nested methods using native AspectJ in Spring Boot

我正在尝试拦截我的应用程序中使用我的自定义开发注释进行注释的任何方法。

最初我使用了运行良好的 Spring AOP。 但是,如果方法调用在同一个目标类中,则不会拦截。 通过官方文档,我知道 Spring AOP 也使用代理 bean。

我发现的一种解决方法是自我注入目标类。 但是,这似乎太过分了。 就像每次将自定义注释添加到方法时一样,我需要确保添加 @Scope 注释,设置 proxyMode 和自注入目标类,如下所示

后来我开始配置和使用本机 AspectJ。

这是我的自定义注释:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackTime {
    String description() default "";
}

这是 TrackTime 注释的方面:

@Configuration
@Slf4j
@Aspect
public class TrackTimeServiceImpl {

    @Pointcut("execution(public * *(..))")
    public void methodsToBeProfiled(){

    }

    @Around("methodsToBeProfiled() && @annotation(x.y.z.TrackTime)")
    public Object audit(ProceedingJoinPoint joinPoint) throws Exception {
        //Business logic
    }
}

我想在这里提一下,我的应用程序正在 Jetty 服务器上运行。

配置文件:

@Configuration
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
@EnableSpringConfigured
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class TrackTimeConfig implements LoadTimeWeavingConfigurer {

    @Override
    public LoadTimeWeaver getLoadTimeWeaver() {
        return new InstrumentationLoadTimeWeaver();
    }

}

aop.xml 文件: 文件路径:/resources/META-INF/aop.xml

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>

    <weaver>
        <!-- only weave classes in our application-specific packages -->
        <include within="in.xxx.*"/>
    </weaver>

    <aspects>
        <!-- weave in just this aspect -->
        <aspect name="in.xxx.yyy.zzz.TrackTimeServiceImpl"/>
    </aspects>

</aspectj>

这里提到了父 pom.xml 中添加的相对依赖项:

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.21</version>
        </dependency>

我的服务等级:

@Component
public class SomeService {

    public void a(){
        b();
    }

    @TrackTime
    public void b(){
        //business logic
    }
}

现在,当从控制器调用方法 a() 时,即使 b() 具有 @TrackTime 注释,它也不会被拦截。

另外,我想提一下,我在运行应用程序时设置了以下程序参数

-javaagent:/Users/xxx/.m2/repository/org/springframework/spring-instrument/5.3.6/spring-instrument-5.3.6.jar
-javaagent:/Users/xxx/.m2/repository/org/aspectj/aspectjweaver/1.9.6/aspectjweaver-1.9.6.jar

我浏览了有关 stackoverflow 的文档、文章和解决方案。 但是,对于上述配置/代码,它不能按我的意愿工作。

向社区寻求帮助。

提前致谢。

我还没有尝试在本地运行您的示例,但乍一看您的代码中有两个细节:

  1. 您正在配置@EnableLoadTimeWeaving (对于本机 AspectJ)和@EnableAspectJAutoProxy (对于 Spring AOP),它们可能相互冲突。 尝试删除后者,看看它是否解决了问题。

  2. aop.xml中,您使用的是<include within="in.xxx.*"/> 请注意,这只会包括直接在in.xxx包中的类,而不包括子包中的类。 为了也包括它们,请在in.xxx..*中使用双点符号。

如果仍然无法使用建议的更改,请随时报告。 那我可以仔细看看。

首先,我要感谢@hfontanez、@void void 和@kriegaex 的回复并帮助我继续解决问题陈述。

因此,如果有人正在寻找如何拦截嵌套和私有方法,让我们将其作为配置本机 AspectJ 的一站式服务。

请在github上查看我的 POC 以获取工作示例。

在我的例子中,我在我的项目结构中添加了 aspectjweaver JAR,并通过 IDE 中的 VM 选项传递了参数。

都这样!! 现在将拦截嵌套/私有方法。

谢谢你,卡提克

暂无
暂无

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

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