Introductions
引入(在 AspectJ 中称为类型间声明)使方面能够声明被建议的对象实现给定接口,并代表这些对象提供该接口的实现。
Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of that interface on behalf of those objects.
你可以使用 @DeclareParents
注释进行引入。该注释用于声明匹配类型有一个新父类(因此得名)。例如,给定一个名为 UsageTracked
的接口和一个名为 DefaultUsageTracked
的该接口的实现,以下方面声明服务接口的所有实现者还实现 UsageTracked
接口(例如,通过 JMX 统计):
You can make an introduction by using the @DeclareParents
annotation. This annotation
is used to declare that matching types have a new parent (hence the name). For example,
given an interface named UsageTracked
and an implementation of that interface named
DefaultUsageTracked
, the following aspect declares that all implementors of service
interfaces also implement the UsageTracked
interface (e.g. for statistics via 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
接口。请注意,在前一个示例的 before 建议中,服务 bean 可以直接用作 UsageTracked
接口的实现。如果你以编程方式访问 bean,则可以编写以下内容:
The interface to be implemented is determined by the type of the annotated field. The
value
attribute of the @DeclareParents
annotation is an AspectJ type pattern. Any
bean of a matching type implements the UsageTracked
interface. Note that, in the
before advice of the preceding example, service beans can be directly used as
implementations of the UsageTracked
interface. If accessing a bean programmatically,
you would write the following:
-
Java
-
Kotlin
UsageTracked usageTracked = context.getBean("myService", UsageTracked.class);
val usageTracked = context.getBean<UsageTracked>("myService")