【问题标题】:Spring: Why is afterPropertiesSet() of InitializingBean needed when there are static and non-static initializers in Java?Spring:当Java中有静态和非静态初始化器时,为什么需要InitializingBean的afterPropertiesSet()?
【发布时间】:2015-06-09 07:58:54
【问题描述】:

我使用afterPropertiesSet() 来初始化 Spring bean 中的类属性。现在我看到这个任务可以通过 Java 内置的静态和非静态初始化程序来完成。我可以用 afterPropertiesSet() 做什么而我不能用初始化程序块?

【问题讨论】:

  • 不,你不能做到这一点。静态块仅用于静态内容,将在加载类时调用/执行。您只能访问静态变量而不是实例变量。 afterPropertiesSet@PostConstruct 是初始化一个特定的对象实例而不是一个类。
  • @M.Deinum 您的评论有资格作为答案。您可以发布它。
  • @M.Deinum 当你发布你的答案时,值得一提的是类构造函数何时可以和不能用于实现相同的目标。
  • @OP 你试过这个吗?当然,这将是找出该方法问题的最简单方法。

标签: java spring spring-mvc


【解决方案1】:

给定以下类

public class MyClass implements InitializingBean {

    static { ... } // static initializer
    { ... }  // non-static initializer

    public void afterPropertiesSet() throws Exception { ... }
}

static 初始化块仅在类被类加载器加载时执行。那时没有该类的实例,此时您只能访问类级别 (static) 变量,而不能访问实例变量。

非静态初始化程序块是在构造对象时但在注入任何属性之前。非静态初始化块实际上被复制到构造函数中。

Java 编译器将初始化程序块复制到每个构造函数中。因此,这种方法可以用来在多个构造函数之间共享一个代码块。

另请参阅Static Initialization Blockshttp://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

afterPropertiesSet@PostConstruct 注解的方法在创建类实例并设置所有属性后调用。例如,如果您想预加载一些可以在此方法中完成的数据,因为所有依赖项都已设置。

如果您只有强制依赖项,则最好使用构造函数注入,而不是使用 InitializingBean@PostConstruct 将初始化逻辑放在构造函数中。这仅在所有依赖项都通过构造函数注入时才有效,如果您通过 set 方法设置了可选依赖项,那么您别无选择,只能使用 @PostConstructInitializingBean

【讨论】:

  • 我可以使用MyService(Dep1 dep1, Optional<Dep2> dep2Optional) 作为构造函数的一部分并完全避免@PostConstruct 吗?
  • 你能和我们分享一下现实生活中的例子吗?
  • @AshokKoyi 是的,你可以。如果您在构造函数调用中处理所有依赖项。
  • 我看到很多人在构造函数块中使用init() 方法来设置他们的类/bean 作为初始化的一部分。
猜你喜欢
  • 2010-09-25
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 2017-08-27
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多