Spring Beanのいわゆるライフサイクルとは、Beanの作成から初期化、破棄までのプロセスを指します。このプロセスは、IOCコンテナによって管理されます。完全なBeanライフサイクルは、SpringBeanライフサイクルを参照できます。ここでは、主にBeanのライフサイクルに関連するいくつかの詳細を記録します。
Beanの初期化と破棄
ライフサイクル全体を通じて、Beanの初期化および破棄フック関数をカスタマイズできます。Beanのライフサイクルが対応する段階に達すると、SpringはカスタムBeanの初期化および破棄メソッドを呼び出します。Beanの初期化および破棄メソッドをカスタマイズする方法は多数あり、以下に1つずつ紹介します。
@豆
前のセクションでは、構成クラスの@Bean
アノテーションを介してBeanを登録できることを紹介しました。また、これを使用してBeanの初期化とメソッドを指定することもできます。
実例を示すために、新しいSpring Bootプロジェクトを作成してから、User
クラスを作成します。
public class User {
public User() {
System.out.println("调用无参构造器创建User");
}
public void init() {
System.out.println("初始化User");
}
public void destory() {
System.out.println("销毁User");
}
}
次に、コンポーネントを構成クラスに登録し、初期化メソッドと破棄メソッドを指定します。
@Configuration
public class WebConfig {
@Bean(initMethod = "init", destroyMethod = "destory")
public User user() {
return new User();
}
}
前記initMethod = "init"
とdestroyMethod = "destory"
Userクラスとinit
、destory
対応する方法。
Spring Bootエントリクラスでテストします。
// 返回 IOC 容器,使用注解配置,传入配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
User user = context.getBean(User.class);
// 关闭 IOC 容器
context.close();
プロジェクトを開始し、コンソール出力を観察します。
上記の出力から、コンテナーが開始される前に、オブジェクトのパラメーターなしコンストラクターが呼び出されてオブジェクトが作成され、次に初期化メソッドが呼び出され、コンテナーが閉じられるときに破棄メソッドが呼び出されることがわかります。
上記の状況はシングルトンの場合ですが、コンポーネントが複数のインスタンスにある場合はどうなりますか?上記のコンポーネント登録構成を複数のケースに変更してから、プロジェクトを再開し、コンソール出力を確認します。
コンソール出力は、前のセクションで説明した内容と一致しています。つまり、マルチケースモードでは、IOCコンテナは起動時にオブジェクトを作成しませんが、取得するたびにオブジェクトを作成するメソッドを呼び出します。その後、オブジェクトが作成されます。次に、初期化メソッドを呼び出します。ただし、コンテナが閉じられた後、Springは対応する破棄メソッドを呼び出しません。これは、マルチケースモードでは、コンテナがこのコンポーネントを管理しないため(必要な場合にのみこのコンポーネントの作成を担当する)、コンテナが管理するためです。 not対応する破棄メソッドは呼び出されません。
InitializingBean&DisposableBean
上記の方法で初期化と破棄の方法を指定することに加えて、Springは初期化と破棄に対応するインターフェースも提供します。
-
InitializingBean
インターフェイスにはafterPropertiesSet
メソッドが含まれています。インターフェイスを実装してから、このメソッドに初期化ロジックを記述できます。 -
DisposableBean
インターフェイスにはdestory
メソッドが含まれています。インターフェイスを実装してから、このメソッドで破棄ロジックを記述できます。
新しいクラスを作成して名前を付けBird
、次の2つのインターフェイスを実装します。
public class Bird implements InitializingBean, DisposableBean {
public Bird() {
System.out.println("调用无参构造器创建Bird");
}
@Override
public void destroy() {
System.out.println("销毁Bird");
}
@Override
public void afterPropertiesSet() {
System.out.println("初始化Bird");
}
}
このコンポーネントを構成クラスに登録します。
@Bean
public Bird bird() {
return new Bird();
}
波をテストする:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
System.out.println("容器创建完毕");
context.close();
プロジェクトを開始し、コンソール出力を観察します。
@ PostConstruct&@ PreDestroy
初期化と破棄の方法を指定する上記の2つの方法に加えて、注釈の変更方法を使用@PostConstruct
して@PreDestroy
、対応する初期化と破棄の方法を指定することもできます。
Fishという名前の新しいクラスを作成します。
public class Fish {
public Fish() {
System.out.println("调用无参构造器创建Fish");
}
@PostConstruct
public void init() {
System.out.println("初始化Fish");
}
@PreDestroy
public void destory() {
System.out.println("销毁Fish");
}
}
このコンポーネントを構成クラスに登録します。
@Bean
public Fish fish(){
return new Fish();
}
波をテストする:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
System.out.println("容器创建完毕");
context.close();
プロジェクトを開始し、コンソール出力を観察します。
効果は上記の2つの方法と同じです。
これらの2つのアノテーションは、Springによって提供されていませんが、JSR250仕様によって提供されています。
BeanPostProcessor
SpringはBeanPostProcessor
、一般にBean事後通知プロセッサとして知られるインターフェースを提供します。これは2つのメソッドpostProcessBeforeInitialization
とを提供しますpostProcessAfterInitialization
。これは、コンポーネントの初期化メソッドが呼び出さpostProcessBeforeInitialization
れる前に実行されpostProcessAfterInitialization
、コンポーネントの初期化メソッドが呼び出された後に実行されます。どちらにも2つの入力パラメーターが含まれています。
-
Bean:現在のコンポーネントオブジェクト。
-
beanName:コンテナ内の現在のコンポーネントの名前。
どちらのメソッドもオブジェクトタイプを返します。現在のコンポーネントオブジェクトを直接返すか、パッケージ化後に返すことができます。
BeanPostProcessor
インターフェイスの実装クラスを定義しましょうMyBeanPostProcessor
:
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " 初始化之前调用");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " 初始化之后调用");
return bean;
}
}
コンポーネントを構成クラスに登録します。
@Bean
public MyBeanPostProcessor myBeanPostProcessor () {
return new MyBeanPostProcessor();
}
プロジェクトを再開し、コンソール出力を確認します。
ご覧のとおり、BeanPostProcessorはIOCコンテナ内のすべてのコンポーネントに有効です。