255

我有一个用例,我只需要在加载 ApplicationContext 时调用 bean 中的(非静态)方法一次。如果我为此使用 MethodInvokingFactoryBean 可以吗?或者我们有更好的解决方案?

作为旁注,我使用 ConfigContextLoaderListener 在 Web 应用程序中加载应用程序上下文。并且想要,如果 bean 'A' 被实例化,只需调用一次 methodA() 。

这怎么能做得很好?

4

6 回答 6

334

To expand on the @PostConstruct suggestion in other answers, this really is the best solution, in my opinion.

  • It keeps your code decoupled from the Spring API (@PostConstruct is in javax.*)
  • It explicitly annotates your init method as something that needs to be called to initialize the bean
  • You don't need to remember to add the init-method attribute to your spring bean definition, spring will automatically call the method (assuming you register the annotation-config option somewhere else in the context, anyway).
于 2009-08-14T08:57:59.763 回答
205

你可以使用类似的东西:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

这将在实例化 bean 时调用“init”方法。

于 2009-07-06T18:37:49.640 回答
108

如参考资料中所述,需要考虑三种不同的方法

使用 init-method 属性

优点:

  • 不需要 bean 来实现接口。

缺点:

  • 源代码中没有立即指示构建后需要此方法以确保正确配置 bean。

实现 InitializingBean

优点:

  • 无需指定init-method,或开启组件扫描/注释处理。
  • 适用于随库提供的 bean,我们不希望使用该库的应用程序关注 bean 生命周期。

缺点:

  • 比 init-method 方法更具侵入性。

使用 JSR-250 @PostConstruct生命周期注解

优点:

  • 在使用组件扫描自动检测 bean 时很有用。
  • 更清楚地表明将使用特定方法进行初始化。意图更接近代码。

缺点:

  • 初始化不再在配置中集中指定。
  • 您必须记住打开注释处理(有时可能会忘记)
于 2009-07-06T23:38:43.840 回答
41

您是否尝试过实施InitializingBean?这听起来正是你所追求的。

缺点是您的 bean 变得支持 Spring,但在大多数应用程序中并没有那么糟糕。

于 2009-07-06T18:35:28.787 回答
8

您可以在应用程序上下文中部署自定义BeanPostProcessor来执行此操作。或者,如果您不介意在 bean 中实现 Spring 接口,则可以使用InitializingBean接口或“init-method”指令(相同链接)。

于 2009-07-06T18:35:49.847 回答
-7

为了进一步清除关于这两种方法的任何混淆,即使用

  1. @PostConstruct
  2. init-method="init"

根据个人经验,我意识到使用 (1) 仅适用于 servlet 容器,而 (2) 适用于任何环境,甚至适用于桌面应用程序。因此,如果您要在独立应用程序中使用 Spring,则必须使用 (2) 来执行“在初始化后调用此方法。

于 2011-05-26T07:14:12.327 回答