Spring AOP 不适用于 Feign Client

Sug*_*lai 5 spring aspectj spring-aop spring-cloud-feign

我有一个 aop 设置

@Target({ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface IgnoreHttpClientErrorExceptions { }

@Aspect
@Component
public class IgnoreHttpWebExceptionsAspect {

@Around(value = "@annotation(annotation)", argNames = "joinPoint, annotation")
public Object ignoreHttpClientErrorExceptions(ProceedingJoinPoint joinPoint, IgnoreHttpClientErrorExceptions annotation)
  throws Throwable {
try {
  //do something
 } catch (HttpClientErrorException ex) {
  //do something
 }
}
Run Code Online (Sandbox Code Playgroud)

如果我@IgnoreHttpClientErrorExceptions在服务层添加这个注释(),

@Service
public class SentenceServiceImpl implements SentenceService {

 @Autowired
 VerbClient verbClient;

 @HystrixCommand(ignoreExceptions = {HttpClientErrorException.class})
 @IgnoreHttpClientErrorExceptions
 public ResponseEntity<String> patch(String accountId, String patch) {
    return verbClient.patchPreferences(accountId, patch);
 }
}
Run Code Online (Sandbox Code Playgroud)

我的AOP被调用了。

@IgnoreHttpClientErrorExceptions但是当我在我的 feign 层添加这个注释( )时。

@FeignClient(value = "account")
@RequestMapping(value = "/url")
public interface VerbClient {

  @RequestMapping(value = "/{id}/preferences", method = RequestMethod.PATCH, consumes = MediaType.APPLICATION_JSON_VALUE)
  @IgnoreHttpClientErrorExceptions
  ResponseEntity<String> patchPreferences(@PathVariable("id") String accountId, String patchJson);
}
Run Code Online (Sandbox Code Playgroud)

AOP 没有被调用。

当我在 feign-layer 中添加注释时,知道为什么 aop 没有被调用吗?

添加的依赖项:

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
 </dependency>
Run Code Online (Sandbox Code Playgroud)

Mạn*_*yễn 1

方法上的注释不应该被继承。

因此 Spring AOP 无法拦截你的方法。

事件@Inherited仅支持从超类到子类的继承。

因此,在这种情况下,您应该尝试另一个切入点,具体取决于您的需要:

// Match all method in interface VerbClient and subclasses implementation
@Around(value = "execution(* com.xxx.VerbClient+.*(..))")

// Match all method in interface VerbClient and subclasses implementation
@Around(value = "execution(* com.xxx.VerbClient+.*(..))")

// Match all method `patchPreferences` in interface VerbClient and subclasses implementation
@Around(value = "execution(* com.xxx.VerbClient+.patchPreferences(..))")

// Or make IgnoreHttpClientErrorExceptions work for Type, 
// and match all method with in annotated interface and subclass implementation
// (@Inherited must be used)
// By this way, you can mark your VerbClient feign interface with this annotation
@Around(value = "execution(* (com.yyy.IgnoreHttpClientErrorExceptions *+).*(..))")
Run Code Online (Sandbox Code Playgroud)