Spring @Configuration Annotation
Die Spring Configuration Annotation ist Teil des Spring Core Frameworks. Die Spring Configuration Annotation zeigt an, dass die Klasse über @Bean-Definitionsmethoden verfügt. So kann der Spring Container die Klasse verarbeiten und Spring Beans generieren, die in der Anwendung verwendet werden.
Spring Configuration
Die Spring Configuration Annotation ermöglicht es uns, Annotationen für Dependency Injection zu verwenden. Lassen Sie uns verstehen, wie man Spring Configuration Klassen erstellt. Lassen Sie uns eine einfache Java-Bean-Klasse erstellen.
package com.journaldev.spring;
public class MyBean {
public MyBean() {
System.out.println("MyBean instance created");
}
}
Bevor wir irgendwelche Klassen des Spring Frameworks verwenden, müssen wir dessen Abhängigkeiten zum Maven-Projekt hinzufügen.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
Jetzt erstellen wir die Spring Configuration Klasse.
package com.journaldev.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfiguration {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
Spring Configuration in der Praxis
Lassen Sie uns eine einfache Klasse schreiben und unsere einfache Spring Configuration Klasse konfigurieren.
package com.journaldev.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(MyConfiguration.class);
ctx.refresh();
// MyBean mb1 = ctx.getBean(MyBean.class);
// MyBean mb2 = ctx.getBean(MyBean.class);
ctx.close();
}
}
Wenn Sie die oben genannte Anwendung ausführen, wird sie folgende Ausgabe produzieren:
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
MyBean instance created
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
Beachten Sie, dass Spring Beans in seinen Kontext lädt, bevor wir sie überhaupt angefordert haben. Dies stellt sicher, dass alle Beans ordnungsgemäß konfiguriert sind und die Anwendung schnell fehlschlägt, wenn etwas schief geht. Auch ctx.refresh() muss aufgerufen werden, sonst erhalten wir folgenden Fehler, wenn wir versuchen, irgendein Bean aus dem Kontext zu holen.
Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@f0f2775 has not been refreshed yet
at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1076)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
at com.journaldev.spring.MySpringApp.main(MySpringApp.java:11)
Wenn Sie die Kommentare entfernen, in denen ich MyBean-Instanzen erhalte, werden Sie bemerken, dass der Konstruktor von MyBean nicht aufgerufen wird. Das liegt daran, dass der Standardbereich von Spring Beans Singleton ist. Wir können dies mit der @Scope Annotation ändern.
Auswirkungen der Entfernung der @Configuration Annotation
Was passiert, wenn wir die @Configuration Annotation entfernen? Was wird geschehen, wenn wir die @Configuration Annotation aus der MyConfiguration Klasse entfernen? Sie werden bemerken, dass es immer noch wie erwartet funktioniert und Spring Beans als Singleton-Klassen registriert und abgerufen werden. Aber in diesem Fall, wenn wir die myBean() Methode aufrufen, wird es ein normaler Java Methodenaufruf sein und wir erhalten eine neue Instanz von MyBean, und sie wird nicht als Singleton bleiben. Um diesen Punkt zu beweisen, definieren wir einen weiteren Bean, der die MyBean-Instanz verwendet.
package com.journaldev.spring;
public class MyBeanConsumer {
public MyBeanConsumer(MyBean myBean) {
System.out.println("MyBeanConsumer created");
System.out.println("myBean hashcode = "+myBean.hashCode());
}
}
Unsere aktualisierte Spring Configuration Klasse sieht wie folgt aus:
package com.journaldev.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//@Configuration
public class MyConfiguration {
@Bean
public MyBean myBean() {
return new MyBean();
}
@Bean
public MyBeanConsumer myBeanConsumer() {
return new MyBeanConsumer(myBean());
}
}
Wenn wir nun die MySpringApp-Klasse ausführen, erzeugt sie folgende Ausgabe.
MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367
Also ist MyBean nun kein Singleton mehr. Jetzt annotieren wir MyConfiguration erneut mit der @Configuration Annotation und führen die MySpringApp-Klasse aus. Diesmal wird die Ausgabe wie unten aussehen.
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856
Es ist also besser, die @Configuration Annotation mit Konfigurationsklassen zu verwenden, um sicherzustellen, dass sich unser Spring Container so verhält, wie wir es möchten. Wenn Sie aus irgendeinem merkwürdigen Grund die @Configuration Annotation nicht verwenden möchten, können wir immer noch unsere Konfigurationsklasse erstellen, indem wir die myBean()-Methode nicht aufrufen und stattdessen eine Instanzvariable von MyBean verwenden, die durch die @Autowired Annotation konfiguriert wird. Etwas wie der folgende Code wird ebenfalls funktionieren.
package com.journaldev.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//@Configuration
public class MyConfiguration {
@Autowired
MyBean myBean;
@Bean
public MyBean myBean() {
return new MyBean();
}
@Bean
public MyBeanConsumer myBeanConsumer() {
return new MyBeanConsumer(myBean);
}
}
Das ist alles zur Spring Configuration Annotation, wir werden in zukünftigen Beiträgen weitere Spring Annotationen betrachten.