SpringBoot構成クラスの@Configurationアノテーションと@beanアノテーション

1. @構成アノテーション

使用法:クラスを操作します。
役割:これが構成クラスであることをSpringBootに通知します。これは、Springのxml構成ファイルと同等です。

@Configuration //告诉SpringBoot这是一个配置类 == 配置文件
public class Config {
    
    
}

2. @ beanアノテーション

使用法:@Beanアノテーションは、コンポーネントをメソッドのIoCコンテナに登録するために、構成クラスで使用されます。デフォルトでは、これも単一のインスタンスです。
役割:コンテナへのコンポーネントの追加は、Springのxml構成ファイルの<bean>タグと同等です。
理解:コンポーネントのIDとしてメソッド名を使用します。戻りタイプはコンポーネントタイプです。戻り値は、コンテナ内のコンポーネントのインスタンスです。

@Configuration //告诉SpringBoot这是一个配置类 == 配置文件
public class Config {
    
    

    @Bean   //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public Person person1(){
    
    
        return new Person("Mr.Yu",21,"male");
    }

    @Bean("customize")  //id值也可以指定
    public Person person2(){
    
    
        return new Person("小明",20,"male");
    }
}

メインプログラムクラスのIoCコンテナ内のオブジェクトを印刷して、person1とcustomizeがコンテナに追加されているかどうかを確認します

@SpringBootApplication
public class MainApplication {
    
    
    public static void main(String[] args) {
    
    
        //1.返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2.查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
    
    
            System.out.println(name);
        }
    }
}

出力結果:出力結果で
ここに写真の説明を挿入
IoCコンテナに保存した2つのオブジェクトがあることがわかります

3.単一インスタンス

@Beanアノテーションが付いたIoCコンテナに格納されているインスタンスも単一のインスタンスです

public static void main(String[] args) {
    
    
        //1.返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2.查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
    
    
            System.out.println(name);
        }

        //单实例
        Person person1 = run.getBean("person1",Person.class);
        Person person2 = run.getBean("person1",Person.class);
        System.out.println("person1 == person2 :"+ (person1 == person2));
}

出力結果:
ここに写真の説明を挿入

4.構成クラスはコンテナーのコンポーネントでもあります

@SpringBootApplication
public class MainApplication {
    
    
    public static void main(String[] args) {
    
    
        //1.返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2.查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
    
    
            System.out.println(name);
        }
        
        //配置类本身也是组件
        Config bean = run.getBean(Config.class);
        //com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
        System.out.println(bean);


    }
}

出力結果:

com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

5.構成クラスのperson1()メソッドを直接呼び出します

構成クラスでperson1()メソッドを直接呼び出すとどうなりますか?それはIoCコンテナーから取得されたものですか、それとも直接新しいオブジェクトですか?

  1. newの構成クラスの場合、person1メソッドを呼び出します。これにより、newのオブジェクトが返されます。
  2. ただし、コンテナから構成クラスを取得すると、person1メソッドが何度削除されても、IoCコンテナから取得されたオブジェクトである同じ単一インスタンスオブジェクトが常に返されます。
@SpringBootApplication
public class MainApplication {
    
    
    public static void main(String[] args) {
    
    
        //1.返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2.查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
    
    
            System.out.println(name);
        }

        //配置类本身也是组件
        Config bean = run.getBean(Config.class);
        //获取到的本身就是代理对象
        //com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
        System.out.println(bean);

        //如果我们直接调用person1方法,它是从IoC容器中拿还是直接new一个对象呢,
        //在new一个配置类出来的情况下,调用person1方法,它返回的是new出来的对象
        Config config = new Config();
        Person person3 = config.person1();
        Person person4 = config.person1();
        System.out.println("person3 == person4 :"+ (person3 == person4));

        //但是如果我们从容器中取得的配置类,无论再去掉用多少次person1方法,它始终返回的都是同一个单实例对象,也就是从IoC容器中拿的对象。
        //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有;
        //保持组件单实例
        Person person5 = bean.person1();
        Person person6 = bean.person1();
        System.out.println("person5 == person6 :"+ (person5 == person6));

    }
}

出力結果:

ここに写真の説明を挿入

6.proxyBeanMethods-プロキシBeanメソッド

コンテナから取得した構成オブジェクトの出力結果:

com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

上記の出力結果では、コンテナから取得した構成クラスオブジェクト自体が、SpringCGLIBによって拡張されたプロキシオブジェクトであることがわかります。

  • @Configuration()のデフォルトはproxyBeanMethods = trueです。
  • @Configuration(proxyBeanMethods = true)の場合、プロキシオブジェクトはメソッドを呼び出します。SpringBootは、このコンポーネントがコンテナにすでに存在するかどうかを常にチェックし、構成クラスのメソッドを呼び出すと、コンテナにすでに存在するコンポーネント(つまり、IoCコンテナにすでに存在するオブジェクト)を返します。
  • @Configuration(proxyBeanMethods = false)の場合、メソッドを呼び出すプロキシオブジェクトではありません。SpringBootはこのコンポーネントがすでにコンテナにあるかどうかをチェックせず、構成クラスのメソッドが呼び出されると新しいオブジェクトが返されます。

@Configuration(proxyBeanMethods = false)例:
上記の5の@Configuration()を@Configuration(proxyBeanMethods = false)に変更します。
出力結果は次のとおりです。
ここに写真の説明を挿入
要約:

  • フルモード(proxyBeanMethods = true):返されるコンポーネントが単一のインスタンスである回数だけ各@Beanメソッドが呼び出されるようにします
  • ライトモード(proxyBeanMethods = false):各@Beanメソッドが呼び出される回数、返されたコンポーネントが新しく作成されます
  • コンポーネントの依存関係は、フルモードのデフォルトを使用する必要があります。他のデフォルトのLiteモードかどうか
  • 構成クラスのコンポーネント間に依存関係はありません。ライトモードは、コンテナの起動プロセスを高速化するために使用されます。構成クラスのメソッドが呼び出されると、SpringBootは毎回オブジェクトがコンテナに存在するかどうかを判断しないため、判断プロセスが削減されます。
  • 構成クラスのコンポーネント間には依存関係があります。構成クラスのメソッドを呼び出すと、SpringBootは毎回オブジェクトがコンテナにすでに存在するかどうかを判断し、フルモードを使用してメソッドを呼び出して前の単一インスタンスコンポーネントを取得します。

おすすめ

転載: blog.csdn.net/MrYushiwen/article/details/111880916