Spring ApplicationContextとBeanの作成について


コミュニティでは、bean構成をどのように表現するかについて多くの困惑があるようです.あるいは、より正確には、bean構成をXMLからJava(またはGroovy、またはKotlin、または......)に変換する方法があります.それは、異なる構成方式が全く異なるように見えるからです.
       しかし実際には、Springを示すためにフォーマット(Java,XML,Properties)で表される構成です.  ApplicationContext(実際にはBeanFactory)これらの定義に従って(aka  BeanDefinition)beanを作成します.A  BeanDefinitionは、基本的にbeanを準備/作成する方法です.
いくつかのクラスを使用して、これらのクラスの内容を深く理解するために小さなサンプルを作成します.
public class Person {

  private String name;

  public void setName(String name) {
    this.name=name;
  }

  public String getName() {
    return this.name;
  }
}

サービスのインタフェース挨拶Person.
public interface Greeter {

  void greet(Person person);
}

標準出力の実装に挨拶文を印刷します.
public class SystemOutGreeter implements Greeter {

  public void greet(Person person) {
    System.out.printf("Greetings %s!%n", person.getName());
  }
}

Propertyファイルを使用した構成
タイムマシンに入り、Springの始まりから15年に戻りましょう.XMLやコメントが出る前にプロパティプロファイルを使用する場合.application-context.propertiesを作成し、ApplicationContextを起動するために使用します.はい、今日もSpring 5を使用しています.プロパティファイルを使用してApplicationContextを作成できます.クラスなどの方法でフレーム内でResourceBundleViewResolverを使用することもできます
person.(class)=biz.deinum.blog.context.springcontexts.Person
person.name=Marten Deinum

greeter.(class)=biz.deinum.blog.context.springcontexts.SystemOutGreeter

これですべてのモバイルコンポーネントを所有し、ApplicationContextを作成します.
public class SpringContextsApplication {

  public static void main(String[] args) throws Exception {
    GenericApplicationContext contextFromProperties =
      new GenericApplicationContext();

    BeanDefinitionReader reader =
      new PropertiesBeanDefinitionReader(contextFromProperties);
    reader.loadBeanDefinitions("classpath:application-context.properties");
    contextFromProperties.refresh();

    doGreeting(contextFromProperties);

    contextFromProperties.stop();
  }

  private static void doGreeting(ApplicationContext ctx) {
    Greeter greeter = ctx.getBean(Greeter.class);
    Person person = ctx.getBean(Person.class);
    greeter.greet(person);
  }
}

では、すべてができました.まずApplicationContextが必要です.そのため、GenericApplicationContext クラスを使用することができます.その後、BeanDefinition sをロードする必要があります.これはBeanDefinitionReaderが機能している場所です.なぜなら、プロパティファイルPropertiesBeanDefinitionReaderを使用する必要があるからです.P r o p e r tiesBeanDefinitionReaderは、プロパティファイルを取得してBeanDefinitionインスタンスに変換します.我々の例では、2つのBeanDefinitionインスタンス、1つは  Personの別の例SystemOutGreeter.特殊な.(class)記号はbeanのタイプを指定します(javadocが表示される詳細があります).Person.name=Marten Deinumもあり、Personのnameプロパティが指定された値に設定されます.反射を使用することでSpringでのデータのバインドとサポートが完了します.
読み込まれたBeanDefinitionsは、BeanFactory(the ApplicationContext is a BeanFactory on steroids)に追加されるので、実際のbeanインスタンスを作成できます.
ApplicationContextを使用する前に、refresh()メソッドを呼び出す必要があります.注意:ほとんどの場合、これは自動的に完了します.
その後、GreeterPersonからApplicationContextと印刷挨拶をもらいました.
出力:  Greetings, Marten Deinum! personおよびgreeter beanを作成した最終結果(前述の反射により)は、次のようになります.
Person person = new Person();
person.setName("Marten Deinum");

および
Greeter greeter = new SystemOutGreeter();

XMLによる構成
今、XMLについて同じことをしましょう.applicationContext.xml構成PersonおよびSystemOutGreeterを作成します.


  

  
    
  

XMLはプロパティファイルよりも詳細です.bean要素があり、beanのタイプを指定するclass属性があります.bean要素の内部では、property要素を指定して設定する属性を指定できます.私たちの例では、name属性を再び所定の値に設定します.
このファイルをロードするには、XMLファイルをロードできるBeanDefinitionReaderのファイルが必要です.そのため、XmlBeanDefinitionReaderを使用します.
public class SpringContextsApplication {

  public static void main(String[] args) throws Exception {
    GenericApplicationContext contextFromXml =
      new GenericApplicationContext();

    BeanDefinitionReader reader =
      new XmlBeanDefinitionReader(contextFromXml);
    reader.loadBeanDefinitions("classpath:applicationContext.xml");
    contextFromXml.refresh();

    doGreeting(contextFromXml);

    contextFromXml.stop();
  }

  private static void doGreeting(ApplicationContext ctx) {
    Greeter greeter = ctx.getBean(Greeter.class);
    Person person = ctx.getBean(Person.class);
    greeter.greet(person);
  }
}

コードは、属性ファイルをロードするのではなく、強調表示された行を除いて、属性ファイルを持つコードとほぼ同じです.XMLファイルを使用して構成されます.出力は同じです.personおよびgreeterの作成は同じであり、再び以下にまとめる.
Person person = new Person();
person.setName("Marten Deinum");

および
Greeter greeter = new SystemOutGreeter();

しかし、通常はこのコードを書くのではなく、ClassPathXmlApplicationContextを使ってこれらの仕事をすべて完了します.
public class SpringContextsApplication {

  public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext contextFromXml =
      new ClassPathXmlApplicationContext("applicationContext.xml");

    doGreeting(contextFromXml);

    contextFromXml.stop();
 }
  ... // Method omitted
}

このコードは、上記のコードと内部で発生する場合とほぼ同じですが、これはずっと短いです.
Javaによる構成
最後に、Javaコードを使用して構成できます.Springでは、Java構成クラスは、注釈@Configurationの方法を使用して注釈する一般的なクラス@Beanである.
@Configuration
public class ApplicationContext {

  @Bean
  public Person person() {
    Person person = new Person();
    person.setName("Marten Deinum");
    return person;
  }

  @Bean
  public SystemOutGreeter greeter() {
    return new SystemOutGreeter();
  }
}

注意:Springでアクセスできないクラスを使用するため、次のコードはコンパイルされません.Springの内部でどのように動作しているかを表示するためだけです(簡略化された形式!).
public class SpringContextsApplication {

  public static void main(String[] args) throws Exception {
    GenericApplicationContext contextFromJava =
      new GenericApplicationContext();

    ConfigurationClassBeanDefinitionReader reader =
      new ConfigurationClassBeanDefinitionReader(contextFromJava);
    reader.loadBeanDefinitions(Collections.singletonSet(
      new ConfigurationClass(ApplicationContext.class, "applicationContext")));
    contextFromJava.refresh();

    doGreeting(contextFromJava);

    contextFromJava.stop();
  }

  private static void doGreeting(ApplicationContext ctx) {
    Greeter greeter = ctx.getBean(Greeter.class);
    Person person = ctx.getBean(Person.class);
    greeter.greet(person);
  }
}

これはSpringがJava構成クラスを見つけたときに起こったことです.しかし、これらはすべてAnnotationConfigApplicationContext Class内に隠されている.
public class SpringContextsApplication {

  public static void main(String[] args) throws Exception {
    AnnotationConfigApplicationContext contextFromJava =
      new AnnotationConfigApplicationContext(ApplicationContext.class);

    doGreeting(contextFromJava);

    contextFromJava.stop();
  }

  private static void doGreeting(ApplicationContext ctx) {
    Greeter greeter = ctx.getBean(Greeter.class);
    Person person = ctx.getBean(Person.class);
    greeter.greet(person);
  }

結論
3つの異なる構成メカニズムのすべての結論を見てみましょう.最初の2つの機構は、@Bean注釈法で発生したものと同じに変換される..(class) forプロパティファイルとclass XMLベースの構成のプロパティに基づいて、Springの結論を出すことができます.  new ()自分.その後、set()がJavaベースの構成のように呼び出されるか、またはがXML構成で使用されるときにコンストラクタパラメータが渡される).
Properties
XML
Java .(class)=Person class=Person
Name of the class person.name=Marten Deinum setName("Marten Deinum")
興味のある人はGitHubでソースコードを見つけることができます.
https://github.com/mdeinum/blog-spring-contexts
本文はグーグルコミュニティから翻訳された.原文住所:https://mdeinum.github.io/2018-04-12-on-spring-applicationcontext-and-bean-creation/