導入

イントロダクション(AspectJ では型間宣言として知られています)は、アスペクトがアドバイスされたオブジェクトが特定のインターフェースを実装することを宣言し、それらのオブジェクトに代わってそのインターフェースの実装を提供できるようにします。

@DeclareParents アノテーションを使って導入することができます。このアノテーションは、一致する型に新しい親があることを宣言するために使用されます(そのため名前が付けられています)。例: UsageTracked という名前のインターフェースと DefaultUsageTracked という名前のそのインターフェースの実装が与えられた場合、次のアスペクトは、サービスインターフェースのすべての実装者が UsageTracked インターフェースも実装することを宣言します(たとえば、JMX を介した統計用):

  • Java

  • Kotlin

@Aspect
public class UsageTracking {

	@DeclareParents(value="com.xyz.service.*+", defaultImpl=DefaultUsageTracked.class)
	public static UsageTracked mixin;

	@Before("execution(* com.xyz..service.*.*(..)) && this(usageTracked)")
	public void recordUsage(UsageTracked usageTracked) {
		usageTracked.incrementUseCount();
	}

}
@Aspect
class UsageTracking {

	companion object {
		@DeclareParents(value = "com.xyz.service.*+",
			defaultImpl = DefaultUsageTracked::class)
		lateinit var mixin: UsageTracked
	}

	@Before("execution(* com.xyz..service.*.*(..)) && this(usageTracked)")
	fun recordUsage(usageTracked: UsageTracked) {
		usageTracked.incrementUseCount()
	}
}

実装されるインターフェースは、アノテーション付きフィールドの型によって決まります。@DeclareParents アノテーションの value 属性は、AspectJ 型のパターンです。一致する型の Bean は、UsageTracked インターフェースを実装します。前の例の前のアドバイスでは、サービス Bean を UsageTracked インターフェースの実装として直接使用できることに注意してください。Bean にプログラムでアクセスする場合、次のように記述します。

  • Java

  • Kotlin

UsageTracked usageTracked = context.getBean("myService", UsageTracked.class);
val usageTracked = context.getBean("myService", UsageTracked.class)