Spring @PostConstructとinit-method属性


103

@PostConstructアノテーションを使用することとinit-method、Spring XML構成と同じメソッドを宣言することの間に違いはありますか?

回答:


153

実際には違いはないと思いますが、動作には優先順位があります。@PostConstructinit-methodBeanPostProcessorsです。

  1. @PostConstructJSR-250アノテーションinit-methodですが、Springは初期化メソッドを持っています。
  2. @PostConstructメソッドがある場合、これは最初に呼び出されてから、初期化メソッドが呼び出されます。
  3. あなたのBean実装がInitializingBeanと上書きした場合afterPropertiesSet、まず@PostConstructそれから、と呼ばれafterPropertiesSet、その後init-method

詳細については、Springのリファレンスドキュメントを確認してください。

JSR 250仕様以前は、xmlでのinit-methodの使用が、Spring固有のクラス/注釈からJavaクラス(Bean)を分離するため、推奨されていました。SpringインフラストラクチャBeanに依存する必要のないライブラリを構築する場合次に、initメソッドの使用が推奨されました。作成中、uは初期化メソッドとして呼び出す必要のあるメソッドを指定できます。

現在、Java EEにJSR 250仕様が導入され、これらのアノテーションがSpringでサポートされるようになったため、Springフレームワークへの依存がある程度軽減されました。

しかし、これらを追加するとコードが読みやすくなることを認めざるを得ないため、両方のアプローチに長所と短所があります。


22
Beanがこれらのメソッドを複数使用しており、初期化の順序に依存している場合、そのBeanは恐ろしく複雑で保守不能になります。
ドナルフェロー2011

2
@ドナルかなり真。これがどのように機能するかについての情報を提供していました。
Aravind A

1
重要な違いがあります:あなたは@PostConstructの仕事をするために、プロセスの注釈に特異的に構成し春に必要:stackoverflow.com/q/3434377/134898
フアン・カレロ

@DonalFellows、ただし認定試験を受ける予定がある場合は、これを知っておく必要があります;)
S.Klechkovski

@DonalFellows-答えを詳しく説明してください。Beanが初期化の順序に依存している場合に直面する困難を意味します。実はどちらがいいか知りたい。PostConstructまたはBean(initMethod = "init")は、リクエストを処理する前にBeanから初期化を行いますか?
アヤスカント2018

19

本当の違いはありません。それはあなたがあなたのシステムをどのように設定したいかによります、そしてそれは個人的な選択の問題です。@PostConstruct私自身、自分のコードにアノテーションを使用することを好み(Beanはメソッドが呼び出された後にのみ正しく構成されているため)、init-methodSpring非対応のライブラリからBeanをインスタンス化するときに使用します(もちろん、アノテーションをそこに適用することはできません!)しかし、私はそれをすべての方法でやりたいと思っている人々を完全に理解することができます。



3

下のBean作成ライフサイクルコールバックの図を見るとわかるように。

Bean作成ライフサイクルコールバック

この3つのステップは、Bean作成ライフサイクルコールバックで発生します。

  1. @PostConstruct呼ばれることが言及されています。
  2. InitializingBeanが実装されている場合は、afterPropertiesSet()呼び出されます。
  3. Bean定義にinit-methodまたはが含まれている場合@Bean(initmethod="..")は、initメソッドを呼び出します。

この図は、Pro Spring 5:Spring Frameworkとそのツールの詳細ガイドからのものです


3

とはBeanの初期化(メソッド)のフェーズで処理されるため 、との間違いがある可能性あります。一方、メソッドはフェーズの完了後に(この場合は、フェーズの開始前に)呼び出されます。編集:したがって、シーケンスは次のとおりです:1)フェーズ、2)メソッドが呼び出されます、3)フェーズ、メソッドを呼び出します@PostConstructinit-method@PostConstructpostProcessAfterInitializationAbstractAutowireCapableBeanFactory.initializeBean()CommonAnnotationBeanPostProcessorinitpostProcessBeforeInitializationpostProcessAfterInitialization
postProcessBeforeInitializationinitpostProcessAfterInitialization@PostConstruct

(補足として、受け入れられた回答からの声明

@ PostConstruct、init-methodはBeanPostProcessorsです

は正しくありません:@PostConstructはによって処理されBeanPostProcessorinitメソッドは正しくありません。)

後に実行されるように()で構成されている一部の(潜在的にカスタム)がそのメソッドで何か深刻なことをしている場合は、違いがありBeanPostProcessorます。 そこnoですデフォルトのSpring構成を持つ任意の違いすべてのため、後に実行されるように構成されているが、中に何もしない方法は。Ordered.getOrder()CommonAnnotationBeanPostProcessorpostProcessBeforeInitialization
BeanPostProcessorsBeanPostProcessorsCommonAnnotationBeanPostProcessorpostProcessBeforeInitialization

結論として、受け入れられた回答などは正しいです... 99%のケースで、この投稿は「悪魔は詳細にある」というコンセプトに敬意を表するためのものです


こんにちは!PostConstructがinit-methodの前に実行される場合、これは混乱します。initProcessがpostProcessBeforeInitializationの後でpostProcessAfterInitializationの前に実行される場合、postProcessAfterInitializationによってどのように処理されますか?
Maxrunner

@Maxrunner、ご迷惑をおかけして申し訳ありません。お知らせいただきありがとうございます。実際、PostConstructがinit-methodの前に実行されると言うつもりはありません。とにかく、私はいくつかの明確化と私の答えを更新
igor.zh

2

ここに完全なコード:https : //github.com/wkaczurba/so8519187spring-boot

注釈の使用:

@Slf4j
@Component
public class MyComponent implements InitializingBean {

    @Value("${mycomponent.value:Magic}")
    public String value;

    public MyComponent() {
        log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
    }

    @PostConstruct
    public void postConstruct() {
        log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
    }

    @Override // init-method; overrides InitializingBean.afterPropertiesSet()
    public void afterPropertiesSet() {
        log.info("MyComponent in afterPropertiesSet: [{}]", value);  // (2) displays: Magic
    }   

    @PreDestroy
    public void preDestroy() {
        log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
    }
}

取得:

org.springframework.contextを更新しています...

コンストラクタでMyComponentの:[ヌル]
MyComponentのpostConstruct中:[マジック]
MyComponentのafterPropertiesSet中:[マジック]
...

起動時にJMX露光用の豆を登録
0.561秒(JVMが1.011のために実行されている)で開始DemoApplication
閉会org.springframework.context ..シャットダウン時のJMX公開Beanの登録解除

...
preDestroyのMyComponent:[Magic]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.