向使用特定注释注释自身的成员添加新注释

问题描述 投票:0回答:1

我想为类的每个成员添加注释,其中成员本身用特定注释进行注释。我必须扩展第三方代码,使其为 Hibernate 二级缓存做好准备 - 在本例中,将

@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY)
添加到特定字段

我正在使用https://mvnrepository.com/artifact/org.aspectj/aspectjrt/1.9.9.1https://mvnrepository.com/artifact/org.aspectj/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

该模式似乎有效,但 AspectJ 告诉我

[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
注释 - 我还必须声明吗?又如何?

java annotations aspectj
1个回答
0
投票

你的语法有点错误:

declare @field :
  (@javax.persistence.OneToOne *) foo.bar.MyEntity : 
  @org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY);

有一个问题:括号中的

(@javax.persistence.OneToOne *)
表示目标是带注释的返回类型。您应该省略括号,然后注释将同样应用于字段定义。这是一个用纯 Java + AspectJ 编写的重现器,带有伪造的注释:

package de.scrum_master.app;

public enum CacheConcurrencyStrategy {
  NONE, NONSTRICT_READ_WRITE, READ_ONLY, READ_WRITE, TRANSACTIONAL
}
package de.scrum_master.app;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(FIELD)
public @interface Cache {
  CacheConcurrencyStrategy usage();
}
package de.scrum_master.app;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(FIELD)
public @interface OneToMany {}
package de.scrum_master.app;

public class Application {
  @OneToMany
  int id;
  String name;

  public static void main(String[] args) throws NoSuchFieldException, SecurityException {
    System.out.println(Application.class.getDeclaredField("id").getDeclaredAnnotation(Cache.class));
  }
}

在没有任何方面的情况下运行它,它将在控制台上打印

null
。现在添加这个方面:

package de.scrum_master.aspect;

import de.scrum_master.app.Cache;
import de.scrum_master.app.OneToMany;
import de.scrum_master.app.CacheConcurrencyStrategy;
import de.scrum_master.app.Application;

public aspect FieldAnnotationAspect {
  declare @field :
    @OneToMany * Application.* : @Cache(usage = CacheConcurrencyStrategy.READ_ONLY);
}

控制台日志现在显示:

@de.scrum_master.app.Cache(usage=READ_ONLY)

它有效,q.e.d。 😉

© www.soinside.com 2019 - 2024. All rights reserved.