为什么aspectj maven-plugin
忽略我的注释继承器。aj文件?我的配置有问题吗?
我想建议项目存储库#getById
与自定义注释:
@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
// AOP does not work, since autogenerated ItemRepositoryImpl#getById
// won't have @MyAnnotation annotation
@MyAnnotation
public Item getById(Long id);
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
}
@Aspect
@Component
public class MyAspects {
@Around("@annotation(MyAnnotation)")
public Object execute(ProceedingJoinPoint joinPoint) {
// This advice works correct when @MyAnnotation is placed on class, I tested.
// The problem is that I have to put @MyAnnotation on interface method
}
}
Spring数据JPA使用接口,Java注释永远不会从接口继承到子类(由于JVM限制)。为了使我的建议适用于自定义注释,有一个小的AspectJ技巧。因此,如前面的引用中所述,我创建了注释继承.aj
文件:
package com.vbakh.somepackage.aspects;
// For some reason does not work. WHY?
public aspect AnnotationInheritor {
declare @method : void ItemRepository+.getById() : @MyAnnotation;
}
并将以下配置添加到我的pom.xml中:
<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<!-- IMPORTANT -->
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.9</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8 </encoding>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.10</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
附言。有没有办法在没有*. aj文件的情况下执行相同的逻辑?意味着使用*. java文件。
我想它应该工作,即使没有注释继承
做了一个小演示,看看……
演示
我把你的代码复制到一个AspectJ项目中(那里没有Spring或SpringAOP)以测试它。我发现了一些问题:
>
@Around(“@annotation(MyAn annotationion)”)
将找不到注释,因为没有完全限定的类名。
< code >声明@method : void ItemRepository。get byid():@ my annotation;与您的接口方法的签名< code>Item getById(Long id)不匹配。
MyAspects.execute(…)
需要抛出Throwable
,当然也返回一些东西,比如joinPoint.proceed()
的结果。但也许那只是草率的复制
修复此问题后,以下MCVE工作得很好:
使项目编译的帮助器类:
package de.scrum_master.app;
public class Item {}
package de.scrum_master.app;
public interface JpaRepository<P, Q> {}
package de.scrum_master.app;
import org.springframework.stereotype.Repository;
@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
Item getById(Long id);
}
package de.scrum_master.app;
public class ItemRepositoryImpl implements ItemRepository {
@Override
public Item getById(Long id) {
return new Item();
}
}
标记批注:
package de.scrum_master.app;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {}
驱动程序应用:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
ItemRepository repository = new ItemRepositoryImpl();
repository.getById(11L);
}
}
方面:
万一你想知道为什么我在切入点时添加了执行(* *(..)),
这是因为我想排除在AspectJ中可用的匹配调用()
连接点,而不是Spring AOP。
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@Around("@annotation(de.scrum_master.app.MyAnnotation) && execution(* *(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(joinPoint);
return joinPoint.proceed();
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.Item;
import de.scrum_master.app.ItemRepository;
import de.scrum_master.app.MyAnnotation;
public aspect AnnotationInheritor {
declare @method : Item ItemRepository+.getById(Long) : @MyAnnotation;
}
控制台日志:
execution(Item de.scrum_master.app.ItemRepositoryImpl.getById(Long))
瞧!它工作得很好。
如果它不适用于您,那么您还有其他问题,例如(但不限于)
>
您顺便提到的“自动生成的ItemRepositoryImpl#getById
”。无论何时何地,在构建过程中生成它,它都需要在方面应用于它之前存在。不过,为了分析这个,我需要GitHub上的MCVE。
要将方面编织到的目标代码是否与方面代码位于同一 Maven 模块中。如果不是,则需要更改 Maven 设置。
我创建了一个自定义的Log4J2Kafka附加器,因为我需要以协议缓冲区格式发送消息。当我运行应用程序时,我看到以下警告。如何使自定义追加器覆盖默认追加器? 插件[kafka]已经映射到类org.apache.logging.log4j.core.appender.mom.kafka.kafkaappender,忽略了类com.abc.appender.kafkaappender 注意:我阅读了h
我正在使用SSIS将数据从平面文件插入数据库。 我已经为此创建了数据流任务。我使用平面文件作为源和ADO NET目标来插入数据。 下面是平面文件源的设置。
10.1.1action通信自定义action文件 action、srv、msg 文件内的可用数据类型一致,且三者实现流程类似: 按照固定格式创建action文件; 编辑配置文件; 编译生成中间文件。 1.定义action文件 首先新建功能包,并导入依赖: roscpp rospy std_msgs actionlib actionlib_msgs; 然后功能包下新建 action 目录,新增 X
我用Cucumber特性文件和Java步骤定义文件进行了一个简单的设置。 feature.feature->StepDefinition.java->PageObject.java 如上所示,我在这里使用了三个步骤定义文件。并且cucumber可以识别这两个文件中的步骤定义。但是当AcceptPage.java文件中定义了“and I Accept”步骤时,它甚至不尝试运行该步骤。如果我将它移动到
sqlcl在格式化缓冲区时似乎使用格式化规则,但在格式化文件时忽略它们。 我有一个输入文件(test.sql)和一小套格式化规则(format.xml) 显示应用于缓冲区而非文件的规则的sqlcl会话: 设置SQLFORMATPATH也不起作用:
我在Spring 4 MVC Security Boot项目中设置了一个自定义身份验证过滤器。过滤器工作正常,现在我想禁用某些URI的安全性(如)。这是我的配置: 不幸的是,当我在下调用资源时,过滤器仍然是链接的。我在过滤器中添加了,并且每次调用都会将其写入控制台。你知道我的配置有什么问题吗? 更新 过滤代码: