使用AspectJ为带特定注解的类成员添加新注解遇@Target警告
问题:使用AspectJ为带特定注解的字段添加Hibernate缓存注解时遇警告
需求背景
我想给第三方类中所有带特定注解的成员添加新注解,使其适配Hibernate二级缓存——具体是给指定字段加上@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY)注解。
使用依赖
- aspectjrt 1.9.9.1
- aspectjtools 1.9.9.1
实现代码
public aspect EntityAspect { declare @field : (@javax.persistence.OneToOne *) foo.bar.MyEntity : @org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY); }
我的目标是:为foo.bar.MyEntity中所有带有@OneToOne注解的成员额外添加@Cache注解。
遇到的警告信息
[java] [iajc] warning at declare @field : (@javax.persistence.OneToMany *) foo.bar.MyEntity : @org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY); [java] [iajc] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [java] [iajc] [..]\EntityAspect.aj:5:0::0 does not match because annotation @javax.persistence.OneToMany has @Target{ElementType.FIELD,ElementType.METHOD} [Xlint:unmatchedTargetKind]
疑问
已知@OneToMany注解带有@Target注解,请问我是否需要对此进行声明?该如何操作?
解决方案
这个警告的核心原因是:@OneToMany(包括你实际使用的@OneToOne)的@Target同时支持字段(FIELD)和方法(METHOD),但你的declare @field切点只针对字段,AspectJ会提醒你该注解还可用于方法场景,当前切点未覆盖这部分,因此抛出unmatchedTargetKind警告。
具体操作
你不需要额外声明@Target,只需根据需求调整切点即可:
- 仅针对字段场景:
保持原有代码不变,若不想看到警告,可在AspectJ编译参数中添加Xlint:-unmatchedTargetKind来关闭该类型警告(因为你明确只关心字段)。 - 同时覆盖字段和方法场景:
将切点从declare @field改为declare @member(@member是AspectJ中同时匹配字段和方法的关键字):public aspect EntityAspect { declare @member : (@javax.persistence.OneToOne *) foo.bar.MyEntity : @org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY); }
关键知识点
declare @field:仅匹配类的字段declare @method:仅匹配类的方法declare @member:同时匹配类的字段和方法
当注解的@Target包含多个目标类型,但你的切点只覆盖其中一部分时,AspectJ就会触发该警告,明确需求后选择对应切点即可。
内容的提问来源于stack exchange,提问作者kartoffel
相关产品推荐
相关产品推荐

