3 回答
TA贡献1951条经验 获得超3个赞
对于你需要做的事情,我会说使用拦截器或装饰器。然而你的拦截器是错误的。首先,您缺少基本部分,即对将调用InvocationContext.proceed()转发给下一个内联拦截器(如果有)或方法调用本身的调用。其次,您放置在那里的注入点非常具体,只有在拦截这种类型的 bean 时才会对您有所帮助。通常,周围调用拦截器方法如下所示:
@AroundInvoke
Object intercept(InvocationContext ctx) throws Exception {
// do something before the invocation of the intercepted method
return ctx.proceed(); // this invoked next interceptor and ultimately the intercepted method
// do something after the invocation of the intercepted method
}
此外,如果您想要有关拦截哪个 bean 的元数据信息,每个拦截器都可以为此注入一个特殊的内置 bean。从元数据中,您可以收集有关当前正在拦截的 bean 的信息。以下是获取元数据的方法:
@Inject
@Intercepted
private Bean<?> bean;
请注意,拦截器不知道它们拦截的类型,它可以是任何类型,因此您通常需要对普通的进行操作Object。如果您需要更具体的东西,CDI 提供了一个装饰器模式,它基本上是一个类型感知拦截器。它有一个特殊的注入点(委托),可以让您直接访问修饰的 bean。它可能更适合您的场景,请查看CDI 规范解释装饰器的这一部分。
TA贡献1773条经验 获得超3个赞
迭代堆栈跟踪来检查TopAlbumsHolder
是否存在并不是一个好方法。为了避免在调用from类
期间调用拦截器,您可以直接在收集数据并将其推送到 中指定调度程序。您可以采用另一种方式,但您的要点是直接调用DataAgent bean 内的而不参与代理(在这种情况下,拦截器将不适用)。getTopAlbums()
DataAgent
DataAgent
TopAlbumsHolder
getTopAlbums()
PS 请注意,缓存的数据应该是不可变的(集合及其对象)。
TA贡献1880条经验 获得超4个赞
有一个误会。您不将被拦截的对象注入到拦截器中,而是使用调用上下文。只需调用即可invocationContext.proceed()
,无需递归。您可以缓存proceed() 的结果。
添加回答
举报