简体   繁体   English

Spring:为什么在Java中存在静态和非静态初始值设定项时需要InitializingBean的afterPropertiesSet()?

[英]Spring: Why is afterPropertiesSet() of InitializingBean needed when there are static and non-static initializers in Java?

I have used afterPropertiesSet() to initialize class properties in Spring beans. 我使用了afterPropertiesSet()来初始化Spring bean中的类属性。 Now I see that this task can be accomplished by Java's built in static and non-static initializers. 现在我看到这个任务可以通过Java的内置静态和非静态初始化器来完成。 What can I do with afterPropertiesSet() that I cannot with the initializer blocks? 我可以用afterPropertiesSet()做什么,我不能使用初始化程序块?

Given the following class 鉴于以下课程

public class MyClass implements InitializingBean {

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

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

The static initializer block is only executed when the class is loaded by the class loader. 静态初始化程序块仅在类加载器加载类时执行。 There is no instance of that class at that moment and you will only be able to access class level ( static ) variables at that point and not instance variables. 此时没有该类的实例,您将只能访问该级别的类级别( static )变量,而不能访问实例变量。

The non-static initializer block is when the object is constructed but before any properties are injected. 非静态初始化程序块是在构造对象时但在注入任何属性之前。 The non-static initializer block is actually copied to the constructor. 实际上,非静态初始化程序块被复制到构造函数中。

The Java compiler copies initializer blocks into every constructor. Java编译器将初始化程序块复制到每个构造函数中。 Therefore, this approach can be used to share a block of code between multiple constructors. 因此,该方法可用于在多个构造函数之间共享代码块。

See also Static Initialization Blocks and http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html 另请参见静态初始化块http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

The afterPropertiesSet or @PostConstruct annotated method is called after an instance of class is created and all the properties have been set. 在创建类的实例并且已设置所有属性之后,将调用afterPropertiesSet@PostConstruct注释方法。 For instance if you would like to preload some data that can be done in this method as all the dependencies have been set. 例如,如果您想要预先加载一些可以在此方法中完成的数据,因为已经设置了所有依赖项。

If you only have mandatory dependencies you might be better of using constructor injection and instead of using InitializingBean or @PostConstruct put the initializing logic in the constructor. 如果您只有强制依赖项,那么最好使用构造函数注入,而不是使用InitializingBean@PostConstruct将初始化逻辑放在构造函数中。 This will only work if all the dependencies are injected through the constructor, if you have optional dependencies set by set methods then you have no choice but to use @PostConstruct or InitializingBean . 这只有在通过构造函数注入所有依赖项时才有效,如果你有set方法设置的可选依赖项,那么你别无选择,只能使用@PostConstructInitializingBean

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM