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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30726189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:04:08  来源:igfitidea点击:

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

javaspringspring-mvc

提问by Alexander Suraphel

I have used afterPropertiesSet()to initialize class properties in Spring beans. Now I see that this task can be accomplished by Java's built in static and non-static initializers. What can I do with afterPropertiesSet()that I cannot with the initializer blocks?

我曾经afterPropertiesSet()在 Spring bean 中初始化类属性。现在我看到这个任务可以通过 Java 内置的静态和非静态初始化器来完成。我能做些什么用afterPropertiesSet(),我无法用初始化语句块?

采纳答案by M. Deinum

Given the following class

鉴于以下类

public class MyClass implements InitializingBean {

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

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

The staticinitializer 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-staticinitializer 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. Therefore, this approach can be used to share a block of code between multiple constructors.

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

See also Static Initialization Blocksand http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

另请参阅静态初始化块http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

The afterPropertiesSetor @PostConstructannotated method is called after an instance of class is created and all the properties have been set. For instance if you would like to preload some data that can be done in this method as all the dependencies have been set.

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

If you only have mandatory dependencies you might be better of using constructor injection and instead of using InitializingBeanor @PostConstructput the initializing logic in the constructor. 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 @PostConstructor InitializingBean.

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