[SPRING] AspectJ : 사용자 정의 * .aj 파일이 무시됩니다.
SPRINGAspectJ : 사용자 정의 * .aj 파일이 무시됩니다.
aspectj-maven-plugin이 내 AnnotationInheritor.aj 파일을 무시하는 이유는 무엇입니까? 내가 잘못 구성 했나요?
내가 조언을 원한다 ItemRepository # 사용자 정의 주석으로 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
}
}
스프링 데이터 JPA 사용 인터페이스 및 Java 주석은 인터페이스에서 하위 클래스로 상속되지 않습니다 (JVM 제한 사항으로 인해). 커스텀 어노테이션에 대한 나의 조언을하기 위해서 약간의 AspectJ 트릭이있다. 따라서 이전 참조에서 설명한 것처럼 AnnotationInheritor.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 파일을 사용합니다.
해결법
-
==============================
1.테스트하기 위해 코드를 AspectJ 프로젝트에 복사했다 (스프링 또는 AOP가 없다). 나는 약간 문제를 찾아 냈다 :
테스트하기 위해 코드를 AspectJ 프로젝트에 복사했다 (스프링 또는 AOP가 없다). 나는 약간 문제를 찾아 냈다 :
이 문제를 해결 한 후 다음 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); } }
상들:
(* * (..))을 Pointcut에 추가 한 이유가 궁금한 경우, AspectJ에서 Spring AOP와는 반대로 사용할 수있는 joinpoint를 제외하고자했기 때문이다.
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))
Voilà! 그것은 잘 작동합니다.
만약 당신이 이것을 좋아하지 않는다면 다른 문제가 있습니다.
-
==============================
2.AnnotationInheritor가 없어도 작동해야합니다.
AnnotationInheritor가 없어도 작동해야합니다.
작은 데모를 만들었습니다.
데모
from https://stackoverflow.com/questions/50391609/aspectj-custom-aj-file-is-ignored by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] SOAP 보안 헤더에서 X509Certificate 가져 오기 (0) | 2019.05.20 |
---|---|
[SPRING] Spring 부팅을 사용하여 현재 활성 프로필을 프로그래밍 방식으로 확인하는 방법 [duplicate] (0) | 2019.05.20 |
[SPRING] web.xml없이 웹 애플리케이션에 Struts2를 추가하는 방법은 무엇입니까? (0) | 2019.05.20 |
[SPRING] 스프링 부트 액츄에이터 상태 표시기 (0) | 2019.05.20 |
[SPRING] 스프링 MVC의 인터셉터 (0) | 2019.05.20 |