Ich lerne Spring 3 und ich scheine die Funktionalität hinter <context:annotation-config>
und nicht zu verstehen <context:component-scan>
.
Von dem, was ich gelesen habe , scheinen sie anders zu behandeln Anmerkungen ( @Required
, @Autowired
etc vs @Component
, @Repository
, @Service
usw.), sondern auch von dem, was ich gelesen habe sie die gleichen registrieren Bean Postprozessor - Klassen.
Um mich noch mehr zu verwirren, gibt es ein annotation-config
Attribut auf <context:component-scan>
.
Kann jemand etwas Licht auf diese Tags werfen? Was ist ähnlich, was ist anders, wird eines von dem anderen abgelöst, sie ergänzen sich gegenseitig, brauche ich einen von beiden?
java
spring
configuration
annotations
spring-3
user938214097
quelle
quelle
component-scan
wann immer möglich verwenden.Antworten:
<context:annotation-config>
wird verwendet, um Anmerkungen in Beans zu aktivieren, die bereits im Anwendungskontext registriert sind (unabhängig davon, ob sie mit XML oder durch Paketscanning definiert wurden).<context:component-scan>
kann auch tun, was<context:annotation-config>
tut, aber<context:component-scan>
auch Pakete scannen, um Beans im Anwendungskontext zu finden und zu registrieren.Ich werde einige Beispiele verwenden, um die Unterschiede / Ähnlichkeiten zu zeigen.
Fängt sich mit einer Grundeinstellung von drei Bohnen vom Typ beginnen
A
,B
undC
mitB
undC
in injiziert werdenA
.Mit folgender XML-Konfiguration:
Das Laden des Kontexts erzeugt die folgende Ausgabe:
OK, dies ist die erwartete Ausgabe. Aber das ist Frühling im "alten Stil". Jetzt haben wir Anmerkungen, also lassen Sie uns diese verwenden, um das XML zu vereinfachen.
Lassen Sie uns zunächst die
bbb
undccc
-Eigenschaften auf BeanA
wie folgt automatisch verdrahten :Dadurch kann ich die folgenden Zeilen aus dem XML entfernen:
Mein XML ist jetzt so vereinfacht:
Wenn ich den Kontext lade, erhalte ich folgende Ausgabe:
OK, das ist falsch! Was ist passiert? Warum sind meine Immobilien nicht automatisch verdrahtet?
Nun, Anmerkungen sind eine nette Funktion, aber für sich genommen tun sie überhaupt nichts. Sie kommentieren nur Sachen. Sie benötigen ein Verarbeitungswerkzeug, um die Anmerkungen zu finden und etwas damit zu tun.
<context:annotation-config>
zur Rettung. Dadurch werden die Aktionen für die Anmerkungen aktiviert, die auf den Beans gefunden werden, die im selben Anwendungskontext definiert sind, in dem sie selbst definiert sind.Wenn ich mein XML in Folgendes ändere:
Wenn ich den Anwendungskontext lade, erhalte ich das richtige Ergebnis:
OK, das ist schön, aber ich habe zwei Zeilen aus dem XML entfernt und eine hinzugefügt. Das ist kein großer Unterschied. Die Idee mit Anmerkungen ist, dass es das XML entfernen soll.
Entfernen wir also die XML-Definitionen und ersetzen sie alle durch Anmerkungen:
Während wir im XML sind, behalten wir nur Folgendes bei:
Wir laden den Kontext und das Ergebnis ist ... Nichts. Es werden keine Bohnen erstellt, keine Bohnen werden automatisch verdrahtet. Nichts!
Das liegt daran, dass, wie ich im ersten Absatz sagte, die
<context:annotation-config />
einzige Funktion für Beans funktioniert , die im Anwendungskontext registriert sind. Da ich die XML-Konfiguration für die drei Beans entfernt habe, wurde keine Bean erstellt und es<context:annotation-config />
gibt keine "Ziele", an denen gearbeitet werden kann.Dies ist jedoch kein Problem, bei
<context:component-scan>
dem ein Paket nach "Zielen" durchsucht werden kann, an denen gearbeitet werden soll. Lassen Sie uns den Inhalt der XML-Konfiguration in den folgenden Eintrag ändern:Wenn ich den Kontext lade, erhalte ich folgende Ausgabe:
Hmmmm ... etwas fehlt. Warum?
Wenn Sie sich die Klassen genau ansehen, hat die Klasse
A
ein Paket,com.yyy
aber ich habe im<context:component-scan>
zu verwendenden Paket angegeben,com.xxx
dass dies meineA
Klasse völlig verfehlt und nur abgeholt hatB
undC
welche auf demcom.xxx
Paket sind.Um dies zu beheben, füge ich auch dieses andere Paket hinzu:
und jetzt bekommen wir das erwartete Ergebnis:
Und das ist es! Jetzt haben Sie keine XML-Definitionen mehr, sondern Anmerkungen.
Als letztes Beispiel, halten die kommentierten Klassen
A
,B
undC
und die folgenden auf die XML, was wir bekommen nach dem Kontext geladen?Wir erhalten immer noch das richtige Ergebnis:
Auch wenn die Bean für die Klasse
A
nicht durch Scannen erhalten wird, werden die Verarbeitungswerkzeuge weiterhin<context:component-scan>
auf alle im Anwendungskontext registrierten Beans angewendet , auch wennA
diese manuell im XML registriert wurden.Aber was ist, wenn wir das folgende XML haben, erhalten wir doppelte Beans, weil wir beide
<context:annotation-config />
und angegeben haben<context:component-scan>
?Nein, keine Duplikate. Wir erhalten wieder das erwartete Ergebnis:
Dies liegt daran, dass beide Tags dieselben Verarbeitungswerkzeuge registrieren (
<context:annotation-config />
kann weggelassen werden, wenn dies<context:component-scan>
angegeben ist), Spring jedoch dafür sorgt, dass sie nur einmal ausgeführt werden.Selbst wenn Sie die Verarbeitungswerkzeuge mehrmals selbst registrieren, stellt Spring sicher, dass sie ihre Magie nur einmal ausführen. dieses XML:
generiert weiterhin das folgende Ergebnis:
OK, das rappt es auf.
Ich hoffe, diese Informationen zusammen mit den Antworten von @Tomasz Nurkiewicz und @Sean Patrick Floyd sind alles, was Sie brauchen, um zu verstehen, wie
<context:annotation-config>
und wie<context:component-scan>
.quelle
Ich fand diese schöne Zusammenfassung, welche Anmerkungen von welchen Erklärungen aufgenommen werden. Wenn Sie es studieren, werden Sie feststellen, dass
<context:component-scan/>
eine Obermenge von Anmerkungen erkannt wird<context:annotation-config/>
, die erkannt werden von :@Component
,@Service
,@Repository
,@Controller
,@Endpoint
@Configuration
,@Bean
,@Lazy
,@Scope
,@Order
,@Primary
,@Profile
,@DependsOn
,@Import
,@ImportResource
Wie Sie sehen können
<context:component-scan/>
, werden die<context:annotation-config/>
Funktionen für das Scannen von CLASSPATH-Komponenten und Java @ Configuration logisch erweitert .quelle
Im Frühling können Sie zwei Dinge tun:
1. Autowiring
Normalerweise definieren Sie in applicationContext.xml Beans und andere Beans werden mit Konstruktor- oder Setter-Methoden verkabelt. Sie können Beans mithilfe von XML oder Anmerkungen verkabeln. Wenn Sie Anmerkungen verwenden, müssen Sie Anmerkungen aktivieren und
<context:annotation-config />
in applicationContext.xml hinzufügen . Dies vereinfacht die Struktur des Tags aus applicationContext.xml , da Sie Beans (Konstruktor oder Setter) nicht manuell verkabeln müssen. Sie können@Autowire
Annotation verwenden und die Beans werden nach Typ verdrahtet.Ein Schritt vorwärts, um der manuellen XML-Konfiguration zu entkommen, ist
2. Autodiscovery
Autodiscovery vereinfacht das XML noch einen Schritt weiter, da Sie das
<bean>
Tag nicht einmal in applicationContext.xml hinzufügen müssen . Sie markieren einfach die spezifischen Beans mit einer der folgenden Anmerkungen, und Spring verbindet die markierten Beans und ihre Abhängigkeiten automatisch mit dem Spring-Container. Die Anmerkungen lauten wie folgt: @Controller , @Service , @Component , @Repository . Durch Verwenden<context:component-scan>
und Zeigen des Basispakets erkennt Spring die Komponenten automatisch und verdrahtet sie mit dem Spring-Container.Als Schlussfolgerung:
<context:annotation-config />
wird verwendet, um die Annotation @Autowired verwenden zu können<context:component-scan />
wird verwendet, um die Suche nach bestimmten Beans und den Versuch der automatischen Verdrahtung zu bestimmen.quelle
<context:annotation-config>
Aktiviert viele verschiedene Annotationen in Beans, unabhängig davon, ob sie in XML oder durch Scannen von Komponenten definiert sind.<context:component-scan>
dient zum Definieren von Beans ohne Verwendung von XMLWeitere Informationen finden Sie unter:
quelle
<context:component-scan>
ich die Bean-Definition nicht mithilfe von XML überschreiben.<context:component-scan>
? Verliere ich etwas, wenn ich das nicht benutze<context:annotation-config>
?Der Unterschied zwischen den beiden ist wirklich einfach!.
Ermöglicht die Verwendung von Anmerkungen, die nur auf die Verkabelung von Eigenschaften und Konstruktoren von Beans beschränkt sind!.
Wohingegen
Ermöglicht alles, was zu
<context:annotation-config />
tun, mit Zusatz von mit Klischees zB ..@Component
,@Service
,@Repository
. Sie können also ganze Bohnen verkabeln und sind nicht nur auf Konstruktoren oder Eigenschaften beschränkt!.quelle
<context:annotation-config>
: Scannen und Aktivieren von Anmerkungen für bereits registrierte Beans in Spring Config XML.<context:component-scan>
: Bohnenregistrierung +<context:annotation-config>
@Autowired und @Required sind Ziele Eigenschaftsniveau so Bohne im Frühjahr IOC vor der Verwendung dieser Zeichen registrieren soll. Um diese Annotationen zu aktivieren, müssen entweder die entsprechenden Beans registriert oder eingeschlossen werden
<context:annotation-config />
. dh<context:annotation-config />
funktioniert nur mit registrierten Bohnen.@Required aktiviert das
RequiredAnnotationBeanPostProcessor
Verarbeitungswerkzeug@Autowired aktiviert das
AutowiredAnnotationBeanPostProcessor
VerarbeitungswerkzeugHinweis: Die Annotation selbst hat nichts zu tun. Wir benötigen ein Verarbeitungstool , eine Klasse darunter, die für den Kernprozess verantwortlich ist.
@Repository, @Service und @Controller sind @Component , und sie zielt auf Klassenebene .
<context:component-scan>
Es scannt das Paket und findet und registriert die Beans. Es enthält die Arbeit von<context:annotation-config />
.Migrieren von XML zu Anmerkungen
quelle
Das
<context:annotation-config>
Tag weist Spring an, die Codebasis zu durchsuchen, um die Abhängigkeitsanforderungen der Klassen mit der Annotation @Autowired automatisch aufzulösen.Spring 2.5 bietet außerdem Unterstützung für JSR-250-Annotationen wie @Resource, @PostConstruct und @ PreDestroy. Für die Verwendung dieser Annotationen müssen bestimmte BeanPostProcessors im Spring-Container registriert sein. Wie immer können diese als einzelne Bean-Definitionen registriert werden, sie können jedoch auch implizit registriert werden, indem das
<context:annotation-config>
Tag in die Federkonfiguration aufgenommen wird.Entnommen aus der Spring-Dokumentation der annotationsbasierten Konfiguration
Spring bietet die Möglichkeit, 'stereotype' Klassen automatisch zu erkennen und entsprechende BeanDefinitions im ApplicationContext zu registrieren.
Laut javadoc von org.springframework.stereotype :
Stereotype sind Anmerkungen, die die Rolle von Typen oder Methoden in der Gesamtarchitektur angeben (eher auf konzeptioneller als auf Implementierungsebene). Beispiel: @Controller @Service @Repository usw. Diese sind für die Verwendung durch Tools und Aspekte vorgesehen (ein ideales Ziel für Pointcuts).
Um solche 'Stereotyp'-Klassen automatisch zu erkennen, ist ein
<context:component-scan>
Tag erforderlich.Das
<context:component-scan>
Tag weist Spring außerdem an, den Code nach injizierbaren Beans unter dem angegebenen Paket (und allen zugehörigen Unterpaketen) zu durchsuchen.quelle
Nur löst die
@Autowired
und@Qualifer
Anmerkungen, das ist alles, es geht um die Injektion Abhängigkeit , Es gibt noch weitere Anmerkungen , die die gleiche Arbeit tun, denke ich , wie@Inject
, aber alles über zu lösen DI durch Anmerkungen.Beachten Sie, dass Sie auch dann, wenn Sie das
<context:annotation-config>
Element deklariert haben, Ihre Klasse als Bean deklarieren müssen. Denken Sie daran, dass wir drei Optionen zur Verfügung haben<bean>
Jetzt mit
Es macht zwei Dinge:
<context:annotation-config>
.Daher, wenn Sie deklarieren
<context:component-scan>
, ist es nicht mehr notwendig, auch<context:annotation-config>
zu deklarieren .Das ist alles
Ein häufiges Szenario war beispielsweise, nur eine Bean über XML zu deklarieren und den DI beispielsweise durch Anmerkungen aufzulösen
Wir haben nur die Beans deklariert, nichts über
<constructor-arg>
und<property>
, der DI wird in ihren eigenen Klassen über @Autowired konfiguriert. Dies bedeutet, dass die Services @Autowired für ihre Repositorys-Komponenten und die Repositorys @Autowired für die JdbcTemplate-, DataSource- usw. Komponenten verwendenquelle
Versuchen Sie es
<context:component-scan base-package="..." annotation-config="false"/>
in Ihrer Konfiguration mit @Service, @Repository, @Component , aber @ Autowired, @ Resource und @Inject funktionieren nicht.Dies bedeutet, dass AutowiredAnnotationBeanPostProcessor nicht aktiviert wird und der Spring-Container die Autowiring-Anmerkungen nicht verarbeitet.
quelle
Der andere wichtige Punkt ist, dass
context:component-scan
implizit die aufgerufen werdencontext:annotation-config
, um die Annotationen auf Beans zu aktivieren. Wenn Siecontext:component-scan
Annotationen nicht implizit für Sie aktivieren möchten , können Sie das Annotation-Config-Element voncontext:component-scan
to weiter festlegenfalse
.Zusammenfassen:
quelle
<context:component-scan base-package="package name" />
::Dies wird verwendet, um dem Container mitzuteilen, dass in meinem Paket Bean-Klassen vorhanden sind. Scannen Sie diese Bean-Klassen. Um Bean-Klassen nach Container über der Bean zu scannen, müssen wir eine der folgenden Stereo-Annotationen schreiben.
@Component
,@Service
,@Repository
,@Controller
<context:annotation-config />
::Wenn wir das Bean-Tag nicht explizit in XML schreiben möchten, weiß der Container, ob in der Bean eine automatische Verkabelung vorhanden ist. Dies ist mithilfe von
@Autowired
Anmerkungen möglich. Wir müssen dem Container mitteilen, dass in meiner Bohne eine automatische Verkabelung vorhanden istcontext:annotation-config
.quelle
Ein
<context:component-scan/>
benutzerdefiniertes Tag registriert denselben Satz von Bean-Definitionen wie von, abgesehen von seiner Hauptverantwortung für das Scannen der Java-Pakete und das Registrieren von Bean-Definitionen aus dem Klassenpfad.Wenn diese Registrierung von Standard-Bean-Definitionen aus irgendeinem Grund vermieden werden soll, müssen Sie dazu im Komponentenscan ein zusätzliches Attribut "annotation-config" angeben:
Referenz: http://www.java-allandsundry.com/2012/12/contextcomponent-scan-contextannotation.html
quelle
<context:annotation-config>
::Dies sagt Spring, dass ich kommentierte Bohnen als Frühlingsbohnen verwenden werde und diese durchverdrahtet würden
@Autowired
Annotation , anstatt in der XML-Datei für die Frühlingskonfiguration zu deklarieren.<context:component-scan base-package="com.test...">
::Dies teilt Spring Container mit, wo mit der Suche nach diesen kommentierten Beans begonnen werden soll. Hier durchsucht spring alle Unterpakete des Basispakets.
quelle
Weitere Informationen finden Sie in der Spring-Kontextschemadatei. Folgendes ist in spring-context-4.3.xsd
quelle
Als Ergänzung können Sie die Verwendung
@ComponentScan
als<context:component-scan>
Annotation verwenden.Es ist auch bei spring.io beschrieben
Wenn Sie Spring Boot verwenden, können Sie @Configuration und @ComponentScan mithilfe der Annotation @SpringBootApplication implizieren.
quelle