1

我有一个豆子:

  • void initialize()用 注释的方法@PostConstruct
  • void release()用 注释的方法@PreDestroy
  • 其他一些方法。
  • 此外,该 bean 具有@Interceptors定义一些拦截器的注释。

其中一个拦截器具有注释的方法

  • @AroundConstruct
  • @AroundInvoke
  • @AroundTimeout
  • @PostConstruct
  • @PreDestroy

在这些方法中的每一个中,我都添加了一些日志记录,因此我可以查看调用了哪些拦截器方法以及何时调用了拦截器方法。调用顺序如下所示:

  • 输入拦截器的@AroundConstruct方法。InvocationContext:目标是null,方法是null,构造函数已设置。
  • 调用 Beans 构造函数。
  • 该调用通过 Interceptor 的@AroundConstruct方法存在。InvocationContext:Target 是 bean 实例,method 是null,构造函数是 set。
  • 拦截器的@PostConstruct方法被调用,调用proceed()并返回。InvocationContext:Target 是 bean 实例,method 是null,构造函数是 set。
  • 在上一次调用完全返回之后,调用 bean 的@PostConstruct方法。

我很惊讶地意识到,@PostConstruct不是在 bean 的@PostConstruct方法调用期间调用,而是在 bean 的构造和调用 bean 的@PostConstruct方法之间调用。此外,bean@PostConstruct方法的调用根本不会被拦截,不会被拦截器的@PostConstruct方法或bi它的@AroundInvoke方法拦截。

我/我的程序方面有什么错误吗?

有没有办法拦截bean的@PostConstruct方法(方法也是如此@PreDestroy)?

我需要准备上下文并用一些内容填充它们。此外,稍后调用堆栈深处的其他方法也可以知道调用是由容器通过这两种方法之一触发的。

4

1 回答 1

1

由于我在互联网上找不到任何答案,因此我进行了一些调试并发现了以下内容(使用 WildFly 15.0.1.Final):

当一个 bean 被实例化时:

  • 进入拦截器的@AroundConstruct(InvocationContext: Constructor set)
  • 执行bean的构造函数
  • 离开拦截器的@AroundConstruct(InvocationContext: Constructur and target set)
  • 进入拦截器的@PostConstruct(InvocationContext: Constructur and target set)
  • 执行bean的@PostConstruct
  • 离开拦截器的@PostConstruct(InvocationContext: Constructur and target set)

这意味着你不知道调用了哪个方法,你只知道@PostConstruct调用了bean的方法。我想这是因为@PostConstructbean 的方法是作为某种拦截器执行的,但这只是我的一个假设。

当你执行一个 bean 的方法时:

  • 进入拦截器的@AroundInvoke(InvocationContext:方法和目标集)
  • 执行bean的方法
  • 离开拦截器的@AroundInvoke(InvocationContext:方法和目标集)

当一个 bean 被销毁时:

  • 进入拦截器的@PreDestroy(InvocationContext:目标集)
  • 执行bean的@PreDestroy
  • 离开拦截器的@PreDestroy(InvocationContext:目标集)

我希望这对其他人也有帮助。

于 2020-01-22T09:21:50.563 回答