コードの量を減らしたい場合は、認識しているAwareSpringBeanをすばやくセットアップしてください

この記事は、ChenPiのJavaLibによるHUAWEICLOUDコミュニティ「 AwareSpringBean 」から共有されています。

春の豆を意識する

通常の状況では、SpringのBeanはSpringを認識しません。つまり、作成されたBeanファクトリ(BeanFactory)を認識できず、ファクトリ内のID、つまりbeanNameを認識できず、Springアプリケーションも認識できません。コンテキストオブジェクト(ApplicationContext)など。

Spring Beanにこの情報を認識させたい場合は、何らかの方法でこの情報を取得し、それをBeanインスタンスに設定できます。この方法の欠点は、知覚する必要のある情報を取得し、それをBeanに積極的に設定する必要があることです。これにより、多くの冗長なコードが書き込まれます。ただし、Springから切り離すことができるという利点があります。

もちろん、Springフレームワークは、Beanを認識させるためのこの拡張性を提供します。Beanクラスに特定のインターフェースを実装させ、その中のメソッドをオーバーライドするだけです。このようにして、Springは、Beanのライフサイクルのある段階でこれらのオーバーライドされたメソッドを呼び出し、認識しておく必要のある情報を注入します。この方法の欠点は、Springと組み合わせる必要があることです。利点は、コードの量を減らすことができ、単純であるということです。

認識インターフェース

SpringのBeanがある程度の認識を得るには、共通の親インターフェースであるAwareインターフェースを持つ特定のインターフェースを実装する必要があります。

package org.springframework.beans.factory;

public interface Aware {
 
}

Awareは、Beanがコールバックメソッドを介してSpringコンテナ内の特定のオブジェクトを取得できることを示すマーカーインターフェイスです。特定のメソッドシグネチャは個々のサブインターフェイスによって定義されますが、通常、単一のパラメータを受け入れてvoidを返すメソッドを1つだけ含める必要があります。

Awareインターフェースを実装するだけでは、デフォルトの機能は提供されないことに注意してください。通常、特定の知覚機能を取得するために、Awareのサブインターフェイスを実装します。

BeanNameAware、BeanFactoryAware、ApplicationContextAware、EnvironmentAware、ApplicationEventPublisherAwareなど、Awareインターフェースには多くのサブインターフェースがあります。一般的な使用法を次に示します。

BeanNameAwareインターフェース

BeanがBeanファクトリで自身のbeanName、つまりSpringコンテナの名前(ID)を知る必要がある場合。このBeanNameAwareインターフェースは実装できます。BeanNameAwareインターフェースのソースコードは次のとおりです。メソッドは1つだけで、beanNameはこのメソッドを介してBeanに設定されます。

package org.springframework.beans.factory;

public interface BeanNameAware extends Aware {
	void setBeanName(String name);
}

実際、私たちが使用するBeanは、通常、beanFactoryでその名前を知る必要はありません。これはほとんど意味がありません。一般に、Spring独自のフレームワークを公式に使用する方が多く、BeanがSpring APIに依存するため、公式には使用を推奨していません。

package com.chenpi;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;

/**
 * @author 陈皮
 * @version 1.0
 * @description
 * @date 2022/4/3
 */
@Component
public class Person implements BeanNameAware {

  private String beanName;

  @Override
  public void setBeanName(String name) {
    this.beanName = name;
  }

  public String getBeanName() {
    return beanName;
  }
}

次のように検証するテストユニットを作成します。

package com.chenpi;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ApplicationTests {

  @Autowired
  private Person person;

  @Test
  public void testValue() {
    System.out.println("Person BeanName:" + person.getBeanName());
  }

}

// 输出结果如下
Person BeanName:person

BeanFactoryAwareインターフェース

Beanが独自のBeanFactoryオブジェクトを構成する場合は、BeanFactoryAwareインターフェースを実装できます。必要に応じて、BeanはコラボレーションのためにBeanFactoryオブジェクトを介して他のBeanオブジェクトを取得できます。もちろん、この方法はお勧めしません。依存するBeanオブジェクトを注入するには、DIメソッドを使用することをお勧めします。BeanFactoryAwareインターフェースのソースコードは次のとおりです。

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;

public interface BeanFactoryAware extends Aware {

    // 在bean属性填充之后,但是在初始回调(例如afterPropertiesSet()方法)之前回调此方法
	void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

テストコードと単体テストの検証結果は次のとおりです。

package com.chenpi;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;

/**
 * @author 陈皮
 * @version 1.0
 * @description
 * @date 2022/4/3
 */
@Component
public class Person implements BeanNameAware, BeanFactoryAware {

  private String beanName;
  private BeanFactory beanFactory;

  @Override
  public void setBeanName(String name) {
    this.beanName = name;
  }

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    this.beanFactory = beanFactory;
  }

  public String getBeanName() {
    return beanName;
  }

  public BeanFactory getBeanFactory() {
    return beanFactory;
  }
}
package com.chenpi;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ApplicationTests {

  @Autowired
  private Person person;

  @Test
  public void testValue() {
    System.out.println("Person BeanName:" + person.getBeanName());
    System.out.println("Person Bean's BeanFactory:" + person.getBeanFactory().getClass());
    System.out.println(
        person == person.getBeanFactory().getBean(person.getBeanName(), Person.class));
  }

}

// 输出结果如下
Person BeanName:person
Person Bean's BeanFactory:class org.springframework.beans.factory.support.DefaultListableBeanFactory
true

ApplicationContextAwareインターフェース

Spring BeanがSpringコンテナー、つまりApplicationContextオブジェクトを認識する必要がある場合は、ApplicationContextAwareインターフェースを実装できます。他のBeanオブジェクトは、コラボレーションのためにSpringコンテナを介して取得できます。

もちろん、BeanオブジェクトがapplicationContext.getResource()メソッドの呼び出しなどのファイルリソースにアクセスする必要がある場合、アプリケーションイベントapplicationContext.publishEvent(ApplicationEvent event)を公開する必要がある場合、またはMessageSourceにアクセスする必要がある場合、このメソッドは次のようになります。実装されました。ただし、これらの特定のシナリオでは、より具体的なResourceLoaderAware、ApplicationEventPublisherAware、またはMessageSourceAwareインターフェイスを実装することをお勧めします。

package org.springframework.context;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;

public interface ApplicationContextAware extends Aware {

	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

テストコードと単体テストの検証結果は次のとおりです。

package com.chenpi;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author 陈皮
 * @version 1.0
 * @description
 * @date 2022/4/3
 */
@Component
public class Person implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {

  private String beanName;
  private BeanFactory beanFactory;
  private ApplicationContext applicationContext;

  @Override
  public void setBeanName(String name) {
    this.beanName = name;
  }

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    this.beanFactory = beanFactory;
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }

  public String getBeanName() {
    return beanName;
  }

  public BeanFactory getBeanFactory() {
    return beanFactory;
  }

  public ApplicationContext getApplicationContext() {
    return applicationContext;
  }
}
package com.chenpi;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

@SpringBootTest
class ApplicationTests {

  @Autowired
  private Person person;

  @Test
  public void testValue() {
    System.out.println("Person BeanName:" + person.getBeanName());
    System.out.println("Person Bean's BeanFactory:" + person.getBeanFactory().getClass());
    System.out.println(
        person == person.getBeanFactory().getBean(person.getBeanName(), Person.class));
    ApplicationContext applicationContext = person.getApplicationContext();
    Person person1 = applicationContext.getBean(person.getBeanName(), Person.class);
    System.out.println(applicationContext.getClass());
    System.out.println(person == person1);
  }

}

// 输出结果如下
Person BeanName:person
Person Bean's BeanFactory:class org.springframework.beans.factory.support.DefaultListableBeanFactory
true
class org.springframework.web.context.support.GenericWebApplicationContext
true

[フォロー]をクリックして、HUAWEI CLOUDの新技術について初めて学びましょう〜

おすすめ

転載: blog.csdn.net/devcloud/article/details/124043234