1. Springコンテナにオブジェクトを追加する方法の紹介
- XML設定ファイルを使用する
- XML 構成ファイルの <bean> タグを使用して Bean を定義し、ClassPathXmlApplicationContext などのコンテナを通じて Bean をロードして初期化します。
- 注釈を使用する
- @Component、@Service、@Controller、@Repository などの Spring によって提供されるアノテーションを使用して Bean を識別します
- 次に、@ComponentScan などのアノテーション スキャナーを介して Bean をロードして初期化します。
- Javaを使用した設定
- Bean は、@Configuration および @Bean アノテーションを使用して Bean を定義するなど、Java コードを使用して構成できます。
- 次に、AnnotationConfigApplicationContext などのコンテナを通じて Bean をロードして初期化します。
- インポートアノテーションを使用する
- @Import アノテーションを使用して他の構成クラスを導入し、コンテナを通じて Bean をロードして初期化します。
- @Import アノテーションには 3 つの使用法があります
- 直接インポート
- ImportSelector インターフェースのバッチ
- ImportBeanDefinitionRegistrar 条件の登録
2. importアノテーション import Beanオペレーション
(1) インポートアノテーションの概要
- import アノテーションは Spring フレームワークのアノテーションで、他の構成クラスや通常の Java クラスを構成クラスに導入するために使用されます。
- @Import アノテーションを使用すると、他の構成クラスまたは Java クラスで定義された Bean を現在の構成クラスに導入できます。
- デフォルトの Bean 名は [クラスの完全修飾名、つまりパッケージ名 + クラス名] です。
(2) アノテーションソースコードのインポート
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
(3)輸入事例実戦
- 自動車関連のインターフェースとクラスエンティティBeanを作成する
//汽车接口
public interface Car {
}
//奔驰类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BenChiCar implements Car{
private String name = "奔驰汽车";
}
//宝马类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaoMaCar implements Car{
private String name = "宝马汽车";
}
//奥迪类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AoDiCar implements Car{
private String name = "奥迪汽车";
}
- 構成クラスマネージャーを作成する
@Configuration
@Import(value = {
BaoMaCar.class, AoDiCar.class, BenChiCar.class})
public class CarBeanManager {
}
- メインクラスのテスト
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//扫描指定的包,包括子包
context.scan("com.lixiang");
//里面完成初始化操作,核心方法
context.refresh();
Map<String, Car> beansOfType = context.getBeansOfType(Car.class);
beansOfType.forEach((k,v)-> System.out.println(k+"="+v));
}
}
3.ImportSelector一括インポートBean操作
(1) importSelector一括インポートの紹介
-
ImportSelectorインターフェースはBeanを動的に登録する機能を実現し、オブジェクトをコンテナに[一括]インポートし、条件に応じて登録が必要なBeanを動的に選択してSpringコンテナに追加する機能を実現します。
-
ImportSelector インターフェイスを実装します。このインターフェイスの selectImports メソッドは String 配列を返します。配列内の値は、追加されるコンポーネントの完全なクラス名です。
(2) importSelectorのソースコード
public interface ImportSelector {
//该方法的返回值是一个String数组,用于指定需要注册的Bean的类名。
String[] selectImports(AnnotationMetadata importingClassMetadata);
@Nullable
default Predicate<String> getExclusionFilter() {
return null;
}
}
(3) 実際の事例
- 私たちは依然として Car エンティティ Bean を使用して Spring コンテナにバッチでインポートし、セレクターをカスタマイズして ImportSelector インターフェイスを実装します。
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[] {
"com.lixiang.domain.AoDiCar","com.lixiang.domain.BaoMaCar","com.lixiang.domain.BenChiCar"};
}
}
- マネージャーでインポート値を変更します
@Configuration
//只需要引入MyImportSelector即可
@Import(value = {
MyImportSelector.class})
public class CarBeanManager {
}
- メインクラスのテスト
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//扫描指定的包,包括子包
context.scan("com.lixiang");
//里面完成初始化操作,核心方法
context.refresh();
Map<String, Car> beansOfType = context.getBeansOfType(Car.class);
beansOfType.forEach((k,v)-> System.out.println(k+"="+v));
}
}
4. BeanDefinitionRegistrar動的登録Bean操作
(1) ImportBeanDefinitionRegistrar インターフェースの概要
- ImportBeanDefinitionRegistrarはSpringフレームワークのインターフェースであり、Beanを動的に登録する機能を実現するために使用されます。
- ImportBeanDefinitionRegistrar は実行時に BeanDefinition を Spring コンテナに動的に登録できます
- ImportSelector とは異なり、ImportSelector は登録する必要がある Bean のクラス名のみを返すことができます。
- @Importアノテーションを使用する場合は、現在の設定クラスにImportBeanDefinitionRegistrarインタフェースを実装したクラスを導入し、Beanを動的に登録する機能を実現します。
(2) ImportBeanDefinitionRegistrarのソースコード
public interface ImportBeanDefinitionRegistrar {
/**
* @param importBeanNameGenerator
* @param annotationMetadata 当前类的注解相关信息
* @param registry IOC容器里面bean的注册信息
*/
default void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
}
/**
* @param annotationMetadata 当前类的注解相关信息
* @param registry IOC容器里面bean的注册信息
*/
default void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
}
}
(3) 実際の事例
- BMW、アウディ、メルセデス・ベンツがすべて存在するとき、新しいエネルギー車が生まれるというシナリオができました。
- 新エネルギー車の主力クラスを創出
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NewEnergyCar implements Car{
private String name = "新能源汽车";
}
- カスタム ImportBeanDefinitionRegistrar を作成する
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
/**
* 可以通过该方法进行手动注册
*/
boolean adCar = beanDefinitionRegistry.containsBeanDefinition("com.lixiang.domain.AoDiCar");
boolean bmCar = beanDefinitionRegistry.containsBeanDefinition("com.lixiang.domain.BaoMaCar");
boolean bcCar = beanDefinitionRegistry.containsBeanDefinition("com.lixiang.domain.BenChiCar");
if (adCar && bmCar && bcCar){
//IOC容器加个混合对象
BeanDefinition beanDefinition = new RootBeanDefinition(NewEnergyCar.class);
beanDefinitionRegistry.registerBeanDefinition("newEnergyCar",beanDefinition);
}
}
}
- Managerでインポートの値を構成する
@Configuration
@Import(value = {
MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class CarBeanManager {
}
- メインクラスのテスト
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//扫描指定的包,包括子包
context.scan("com.lixiang");
//里面完成初始化操作,核心方法
context.refresh();
Map<String, Car> beansOfType = context.getBeansOfType(Car.class);
beansOfType.forEach((k,v)-> System.out.println(k+"="+v));
}
}
(4) BeanDefinition の概要
- Spring コンテナの最も重要な概念の 1 つであり、コンテナが Bean インスタンスを作成および管理し、Bean 定義情報を抽象化およびカプセル化するための基礎となります。
- Beanの名前、タイプ、スコープ、属性などのBeanの定義情報を記述します。
- Beanのスコープの指定、遅延ロードするかどうか、自動インジェクトするかどうかなど、Beanの作成と管理を詳細に設定および制御できます。