Einführung in Spring

Das Spring-Framework wurde von Rod Johnson entwickelt und die erste Version wurde 2004 veröffentlicht. Spring ist ein Framework, das aus der tatsächlichen Entwicklung extrahiert wurde, daher übernimmt es viele gängige Schritte in der Entwicklung und überlässt Entwicklern nur die anwendungsspezifischen Teile, was die Entwicklungseffizienz von Unternehmensanwendungen erheblich verbessert.

Die Vorteile von Spring lassen sich wie folgt zusammenfassen:

  • Wenig invasives Design mit sehr geringer Code-Verschmutzung.
  • Unabhängig von verschiedenen Anwendungsservern. Anwendungen, die auf dem Spring-Framework basieren, können das Versprechen "Write Once, Run Anywhere" wirklich einlösen.
  • Der IoC-Container von Spring reduziert die Komplexität beim Austausch von Business-Objekten und verbessert die Entkopplung zwischen Komponenten.
  • Die AOP-Unterstützung von Spring ermöglicht es, gemeinsame Aufgaben wie Sicherheit, Transaktionen und Protokollierung zentral zu verwalten und bietet dadurch eine bessere Wiederverwendung.
  • Springs ORM und DAO bieten eine gute Integration mit Persistenz-Frameworks von Drittanbietern und vereinfachen den Low-Level-Datenbankzugriff.
  • Spring ist sehr offen und zwingt Anwendungen nicht, sich vollständig auf Spring zu verlassen. Entwickler können frei wählen, ob sie einen Teil oder das gesamte Spring-Framework verwenden.

Das Kompositionsstrukturdiagramm des Spring-Frameworks ist wie folgt:

spring-overview

Springs Kernmechanismus

Verwalten von Beans

Programme greifen hauptsächlich über den Spring-Container auf die Beans im Container zu. ApplicationContext ist die am häufigsten verwendete Schnittstelle des Spring-Containers. Diese Schnittstelle hat die folgenden zwei Implementierungsklassen:

  • ClassPathXmlApplicationContext: Sucht nach Konfigurationsdateien im Klassenladepfad und erstellt den Spring-Container basierend auf den Konfigurationsdateien.
  • FileSystemXmlApplicationContext: Sucht nach Konfigurationsdateien in einem relativen oder absoluten Pfad im Dateisystem und erstellt den Spring-Container basierend auf den Konfigurationsdateien.
public class BeanTest{
    public static void main(String args[]) throws Exception{
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        Person p = ctx.getBean("person", Person.class);
        p.say();
    }
}

Verwenden von Spring in Eclipse

In IDE-Tools wie Eclipse können Benutzer ihre eigenen erstellenUser Library, und dann legen sie alle Spring-JAR-Pakete hinein. Natürlich können sie JAR-Pakete auch direkt in das Projekt-/WEB-INF/libVerzeichnis. Wenn jedochUser Library, wenn das Projekt veröffentlicht wird, müssen die von der Benutzerbibliothek referenzierten JAR-Dateien zusammen mit der Anwendung veröffentlicht werden, das heißt, kopieren Sie die von der Benutzerbibliothek verwendeten JAR-Dateien in das/WEB-INF/libVerzeichnis. Der Grund dafür ist, dass Eclipse beim Bereitstellen einer Webanwendung die JAR-Dateien aus der Benutzerbibliothek nicht in das/WEB-INF/libVerzeichnis kopiert, und manuelles Kopieren ist erforderlich.

Dependency Injection

Das Spring-Framework hat zwei Kernfunktionen:

  • Der Spring-Container fungiert als Superfabrik und ist für das Erstellen und Verwalten aller Java-Objekte verantwortlich. Diese Java-Objekte werden Beans genannt.
  • Der Spring-Container verwaltet die Abhängigkeiten zwischen Beans im Container. Spring verwendet eine Methode namens "Dependency Injection", um die Abhängigkeiten zwischen Beans zu verwalten.

Mit Dependency Injection können Sie nicht nur gewöhnliche Eigenschaftswerte in Beans injizieren, sondern auch Referenzen auf andere Beans injizieren. Dependency Injection ist eine hervorragende Entkopplungsmethode, mit der Beans über Konfigurationsdateien organisiert werden können, anstatt auf hartcodierte Weise miteinander gekoppelt zu sein.

Dependency Injection verstehen

Rod Johnson war der Erste, der der Verwaltung der kollaborativen Beziehungen von Java-Instanzen durch Konfigurationsdateien große Bedeutung beimaß. Er gab dieser Methode einen Namen: Inversion of Control (IoC). Später gab Martine Fowler ihr einen anderen Namen: Dependency Injection. Daher ist die Bedeutung genau dieselbe, ob es sich um Dependency Injection oder Inversion of Control handelt. Wenn ein Java-Objekt (der Aufrufer) eine Methode eines anderen Java-Objekts (des abhängigen Objekts) aufrufen muss, gibt es im traditionellen Modell normalerweise zwei Ansätze:

  1. Ursprünglicher Ansatz: Der Aufrufer erstelltaktivdas abhängige Objekt und ruft dann die Methode des abhängigen Objekts auf.
  2. Einfaches Factory-Muster: Der Aufrufer findet zuerst die Factory des abhängigen Objekts und holt dannaktivdas abhängige Objekt über die Factory und ruft schließlich die Methode des abhängigen Objekts auf.

Beachten Sie das"aktiv"oben. Dies führt unweigerlich zu einer fest codierten Kopplung zwischen dem Aufrufer und der Implementierungsklasse des abhängigen Objekts, was für Projekt-Upgrade und -Wartung sehr ungünstig ist. Nach der Verwendung des Spring-Frameworks muss der Aufrufer nicht mehraktivdas abhängige Objekt zu beziehen. Der Aufrufer muss lediglichpassivakzeptieren, dass der Spring-Container den Membervariablen des Aufrufers Werte zuweist. Es ist ersichtlich, dass sich nach der Verwendung von Spring die Art und Weise, wie der Aufrufer das abhängige Objekt bezieht, von aktiver Beschaffung zu passiver Annahme ändert – deshalb nannte Rod Johnson es Inversion of Control.

Darüber hinaus ist aus Sicht des Spring-Containers der Spring-Container dafür verantwortlich, das abhängige Objekt den Membervariablen des Aufrufers zuzuweisen – was dem Injizieren der Instanz, von der er abhängt, in den Aufrufer entspricht. Daher nannte Martine Fowler es Abhängigkeitsinjektion.

Setter-Injektion

Setter-Injektion bedeutet, dass der IoC-Container abhängige Objekte über die Setter-Methoden der Membervariablen injiziert. Diese Injektionsmethode ist einfach und intuitiv, daher wird sie in Springs Abhängigkeitsinjektion weit verbreitet eingesetzt.

Konstruktor-Injektion

Die Art und Weise, Abhängigkeiten mithilfe von Konstruktoren festzulegen, wird als Konstruktor-Injektion bezeichnet. Einfach ausgedrückt, veranlasst sie Spring dazu, im Hintergrund über Reflexion einen Konstruktor mit angegebenen Parametern auszuführen. Wenn der parametrisierte Konstruktor ausgeführt wird, können die Konstruktorparameter verwendet werden, um Membervariablen zu initialisieren – das ist das Wesen der Konstruktor-Injektion.

Vergleich der beiden Injektionsmethoden

Die Setter-Injektion hat folgende Vorteile:

  • Sie ähnelt eher der traditionellen JavaBean-Schreibweise, was es Entwicklern erleichtert, sie zu verstehen und zu akzeptieren. Das Festlegen von Abhängigkeiten über Setter-Methoden ist intuitiver und natürlicher.
  • Bei komplexen Abhängigkeiten kann der Konstruktor, wenn Konstruktorinjektion verwendet wird, zu aufgebläht und schwer lesbar werden. Wenn Spring eine Bean-Instanz erstellt, muss es gleichzeitig auch alle zugehörigen abhängigen Instanzen instanziieren, was zu Leistungseinbußen führt. Setter-Injektion kann diese Probleme vermeiden.
  • Besonders wenn einige Mitgliedsvariablen optional sind, sind Konstruktoren mit mehreren Parametern noch umständlicher.

Die Vorteile der Konstruktorinjektion sind wie folgt:

  • Bei der Konstruktorinjektion lässt sich die Injektionsreihenfolge der Abhängigkeiten im Konstruktor festlegen, wobei Abhängigkeiten mit höherer Priorität zuerst injiziert werden.
  • Für Beans, deren Abhängigkeiten sich nicht ändern müssen, ist die Konstruktorinjektion nützlicher. Da es keine Setter-Methoden gibt, werden alle Abhängigkeiten im Konstruktor festgelegt, sodass keine Sorge besteht, dass nachfolgender Code die Abhängigkeitsbeziehungen beschädigt.
  • Wenn Abhängigkeiten nur im Konstruktor festgelegt werden können, kann nur der Ersteller der Komponente die Abhängigkeiten der Komponente ändern. Für den Aufrufer der Komponente sind die internen Abhängigkeitsbeziehungen der Komponente vollständig transparent, was eher dem Prinzip hoher Kohäsion entspricht.

Hinweis:
Es wird empfohlen, Setter-Injektion als Hauptansatz und Konstruktorinjektion als Ergänzung zu verwenden. Für Injektionen, bei denen sich die Abhängigkeitsbeziehung nicht ändern muss, sollte nach Möglichkeit Konstruktorinjektion verwendet werden; für andere Abhängigkeitsinjektionen sollte Setter-Injektion in Betracht gezogen werden.

Beans im Spring-Container

Für Entwickler umfasst die Verwendung des Spring-Frameworks hauptsächlich zwei Dinge: ① Beans entwickeln; ② Beans konfigurieren. Für das Spring-Framework besteht die Aufgabe darin, gemäß der Konfigurationsdatei Bean-Instanzen zu erstellen und die Methoden der Bean-Instanzen aufzurufen, um die „Abhängigkeitsinjektion“ abzuschließen – das ist das Wesen des sogenannten IoC.

Geltungsbereiche von Beans im Container

Wenn Sie eine Bean-Instanz über den Spring-Container erstellen, können Sie nicht nur die Bean-Instanz instanziieren, sondern auch einen bestimmten Scope für die Bean angeben. Spring unterstützt die folgenden fünf Scopes:

  1. singleton: Singleton-Modus. Im gesamten Spring-IoC-Container wird für eine Bean mit dem Singleton-Scope nur eine einzige Instanz erstellt.
  2. prototype: Jedes Mal, wenn eine Bean mit Prototype-Scope über die getBean()-Methode des Containers abgerufen wird, wird eine neue Bean-Instanz erstellt.
  3. request: Für eine HTTP-Anfrage erzeugt eine Bean mit Request-Scope nur eine einzige Instanz. Das bedeutet, dass das Programm innerhalb derselben HTTP-Anfrage jedes Mal dieselbe Instanz erhält, wenn es diese Bean anfordert. Dieser Scope ist nur dann wirklich wirksam, wenn Spring in einer Webanwendung verwendet wird.
  4. session: Dieser Scope beschränkt die Definition der Bean auf eine HTTP-Session. Er ist nur im Kontext eines web-aware Spring ApplicationContext gültig.
  5. global session: Jede globale HTTP-Session entspricht einer Bean-Instanz. In typischen Fällen ist er nur bei Verwendung eines Portlet-Kontexts wirksam und ebenfalls nur in Webanwendungen gültig.

Wenn der Bean-Scope nicht angegeben wird, verwendet Spring standardmäßig den Singleton-Scope. Das Erstellen und Zerstören von Beans mit Prototype-Scope ist relativ aufwändig. Im Gegensatz dazu kann eine Bean-Instanz mit Singleton-Scope nach ihrer Erstellung wiederverwendet werden. Daher sollten Sie versuchen, Beans nicht auf den Prototype-Scope zu setzen.

Kollaborierende Beans mit Autowiring injizieren

Spring kann die Abhängigkeiten zwischen Beans automatisch verdrahten. Das heißt, die abhängige Bean muss nicht explizit mit ref angegeben werden. Stattdessen untersucht der Spring-Container den Inhalt der XML-Konfigurationsdatei und injiziert die Bean, von der die aufrufende Bean abhängt, nach bestimmten Regeln in die aufrufende Bean.
Spring-Autowiring kann über das<beans/>Elementedefault-autowireAttribut angegeben werden. Dieses Attribut gilt für alle Beans in der Konfigurationsdatei. Es kann auch über das<bean/>ElementeautowireAttribut angegeben werden, das nur diese Bean betrifft.

autowireunddefault-autowireEs kann die folgenden Werte akzeptieren:

  • no: Autowiring wird nicht verwendet. Bean-Abhängigkeiten müssen über das ref-Element definiert werden. Dies ist die Standardkonfiguration. In größeren Bereitstellungsumgebungen wird davon abgeraten, diese Konfiguration zu ändern; die explizite Konfiguration von Kollaborateuren kann klarere Abhängigkeitsbeziehungen erzeugen.
  • byName: Autowiring basierend auf Setter-Methodennamen. Der Spring-Container durchsucht alle Beans im Container, findet eine Bean, deren id mit dem Setter-Methodennamen übereinstimmt, nachdem das Präfix "set" entfernt und der erste Buchstabe kleingeschrieben wurde, und führt die Injektion durch. Wenn keine passende Bean-Instanz gefunden wird, führt Spring keine Injektion durch.
  • byType: Autowiring basierend auf dem Parametertyp der Setter-Methode. Der Spring-Container sucht alle Beans im Container. Wenn genau eine Bean vorhanden ist, deren Typ mit dem Parametertyp der Setter-Methode übereinstimmt, wird diese Bean automatisch injiziert; wenn mehrere solche Beans gefunden werden, wird eine Ausnahme ausgelöst; wenn keine solche Bean gefunden wird, passiert nichts und die Setter-Methode wird nicht aufgerufen.
  • constructor: Ähnlich wie byType, außer dass es verwendet wird, um Konstruktorparameter automatisch abzugleichen. Wenn der Container nicht genau eine Bean finden kann, die mit dem Konstruktorparametertyp übereinstimmt, wird eine Ausnahme ausgelöst.
  • autodetect: Der Spring-Container entscheidet selbst, ob er anhand der internen Struktur der Bean die Konstruktor- oder die byType-Strategie verwendet. Wenn ein Standardkonstruktor gefunden wird, wird die byType-Strategie angewendet.

Wenn ein Bean sowohl autowired-Abhängigkeiten als auch explizit über ref angegebene Abhängigkeiten verwendet, überschreiben die explizit angegebenen Abhängigkeiten die autowired-Abhängigkeiten. Für große Anwendungen wird von Autowiring abgeraten. Obwohl Autowiring den Arbeitsaufwand für Konfigurationsdateien verringern kann, reduziert es die Klarheit und Transparenz der Abhängigkeitsbeziehungen erheblich. Die Abhängigkeitsassemblierung stützt sich auf Eigenschaftsnamen und Eigenschaftstypen in Quelldateien, wodurch die Kopplung zwischen Beans auf die Codeebene reduziert wird, was einer Entkopplung auf hoher Ebene nicht zuträglich ist.

<!--通过设置可以将Bean排除在自动装配之外-->
<bean id="" autowire-candidate="false"/>

<!--除此之外,还可以在beans元素中指定,支持模式字符串,如下所有以abc结尾的Bean都被排除在自动装配之外-->
<beans default-autowire-candidates="*abc"/>

Drei Möglichkeiten zum Erstellen von Beans

Erstellen von Bean-Instanzen mit Konstruktoren

Die Verwendung eines Konstruktors zum Erstellen einer Bean-Instanz ist der häufigste Fall. Wenn keine Konstruktorinjektion verwendet wird, ruft Spring intern den parameterlosen Konstruktor der Bean-Klasse auf, um die Instanz zu erstellen. Daher muss die Bean-Klasse einen parameterlosen Konstruktor bereitstellen.

Bei Verwendung des Standardkonstruktors zum Erstellen einer Bean-Instanz führt Spring eine Standardinitialisierung aller Eigenschaften der Bean-Instanz durch, d. h. alle Werte primitiver Typen werden auf 0 oder false initialisiert und alle Werte von Referenztypen werden auf null initialisiert.

Erstellen von Beans mit statischen Factory-Methoden

Wenn eine statische Factory-Methode zum Erstellen einer Bean-Instanz verwendet wird, muss auch das class-Attribut angegeben werden. Zu diesem Zeitpunkt gibt das class-Attribut jedoch nicht die Implementierungsklasse der Bean-Instanz an, sondern die statische Factory-Klasse. Spring verwendet dieses Attribut, um zu wissen, welche Factory-Klasse die Bean-Instanz erstellt.

Darüber hinaus muss das factory-method-Attribut verwendet werden, um die statische Factory-Methode anzugeben. Spring ruft die statische Factory-Methode auf, um eine Bean-Instanz zurückzugeben. Sobald die angegebene Bean-Instanz erhalten wurde, sind die nachfolgenden Verarbeitungsschritte von Spring genau dieselben wie beim Erstellen einer Bean-Instanz mit einer gewöhnlichen Methode. Wenn die statische Factory-Methode Parameter benötigt, verwenden Sie die<constructor-arg.../>Element zur Angabe der Parameter der statischen Factory-Methode.

Erstellen von Beans durch Aufrufen von Instanz-Factory-Methoden

Der einzige Unterschied zwischen einer Instanz-Factory-Methode und einer statischen Factory-Methode besteht darin, dass zum Aufrufen einer statischen Factory-Methode nur eine Factory-Klasse erforderlich ist, während zum Aufrufen einer Instanz-Factory-Methode eine Factory-Instanz erforderlich ist. Bei Verwendung einer Instanz-Factory-Methode benötigt das<bean.../>Element nicht das class-Attribut. Um eine Instanz-Factory-Methode zu konfigurieren, verwenden Siefactory-beanum die Factory-Instanz anzugeben.
Die<bean.../>Element zum Erstellen eines Beans mithilfe einer Instanz-Factory-Methode erfordert die Angabe der folgenden zwei Attribute:

  • factory-bean: Der Wert dieses Attributs ist die id des Factory-Beans.
  • factory-method: Dieses Attribut gibt die Factory-Methode der Instanz-Factory an.

Wenn beim Aufrufen der Instanz-Factory-Methode Parameter übergeben werden müssen, verwenden Sie das<constructor-arg.../>Element, um die Parameterwerte zu bestimmen.

Koordinieren von Beans mit unterschiedlichen Scopes

Wenn ein Bean mit Singleton-Scope von einem Bean mit Prototype-Scope abhängt, tritt ein Synchronisationsproblem auf. Das liegt daran, dass der Spring-Container beim Initialisieren allesingleton Bean, und dasingleton Beanhängt ab vonprototype Bean, wenn Spring initialisiert wirdsingleton Beanzuvor wird es zuerst erzeugenprototypeBean— und erst dann erzeugensingleton Bean, und dannprototype Beaninjizierensingleton Bean。
Es gibt zwei Möglichkeiten, das Synchronisationsproblem zu lösen:

  • Verzicht auf Abhängigkeitsinjektion: Immer wenn eine Singleton-Scope-Bean eine Prototype-Scope-Bean benötigt, fordert sie aktiv eine neue Bean-Instanz vom Container an, wodurch sichergestellt wird, dass jede injizierteprototype BeanInstanz ist die neueste Instanz.
  • Verwendung von Method Injection: Method Injection verwendet normalerweise Lookup Method Injection. Lookup Method Injection ermöglicht es dem Spring-Container, abstrakte oder konkrete Methoden von Beans im Container zu überschreiben und das Ergebnis der Suche nach anderen Beans im Container zurückzugeben. Die nachgeschlagene Bean ist normalerweise einenon-singleton Bean. Spring erfüllt die oben genannte Anforderung, indem es JDK Dynamic Proxies oder die cglib-Bibliothek verwendet, um den Binärcode des Clients zu ändern.

Es wird empfohlen, die zweite Methode zu verwenden, die Method Injection. Um Lookup Method Injection zu verwenden, sind ungefähr die folgenden zwei Schritte erforderlich:

  1. Definieren Sie die Implementierungsklasse der aufrufenden Bean als abstrakte Klasse und definieren Sie eine abstrakte Methode, um die Bean, von der sie abhängt, zu erhalten.
  2. In<bean.../>Fügen Sie das<lookup-method.../>untergeordnete Element zum Element hinzu, wobei Spring die angegebene abstrakte Methode für die Implementierungsklasse der aufrufenden Bean implementiert.

Hinweis:

Spring wird eine dynamische Erweiterung zur Laufzeit verwenden, um die<lookup-method.../>durch das Element angegebene abstrakte Methode zu implementieren. Wenn die abstrakte Zielklasse eine Schnittstelle implementiert hat, verwendet Spring einen dynamischen JDK-Proxy, um die abstrakte Klasse zu implementieren und die abstrakte Methode dafür zu implementieren; wenn die abstrakte Zielklasse keine Schnittstelle implementiert hat, verwendet Spring cglib, um die abstrakte Klasse zu implementieren und die abstrakte Methode dafür zu implementieren. Die cglib-Bibliothek wurde in Spring 4.0 bereits in das Paket spring-core-xxx.jar integriert.

Zwei Arten von Post-Prozessoren

Spring bietet zwei häufig verwendete Post-Prozessoren:

  • Bean-Post-Prozessor: Dieser Post-Prozessor führt eine Nachbearbeitung von Beans im Container durch und bietet zusätzliche Erweiterungen für die Beans.
  • Container-Post-Prozessor: Dieser Post-Prozessor führt eine Nachbearbeitung des IoC-Containers durch, um die Containerfunktionalität zu erweitern.

Bean-Post-Prozessor

Ein Bean-Post-Prozessor ist eine besondere Art von Bean. Diese spezielle Bean bietet keine Dienste nach außen an und kann sogar das id-Attribut weglassen. Sie ist hauptsächlich dafür verantwortlich, andere Beans im Container nachzubearbeiten, z. B. Proxys für Ziel-Beans im Container zu erzeugen. Diese Art von Bean wird als Bean-Post-Prozessor bezeichnet. Nachdem eine Bean-Instanz erfolgreich erstellt wurde, führt der Bean-Post-Prozessor eine weitere Erweiterungsverarbeitung an der Bean-Instanz durch. Ein Bean-Post-Prozessor muss dieBeanPostProcessorSchnittstelle implementieren und muss beide Methoden dieser Schnittstelle implementieren.

  1. Object postProcessBeforeInitialization(Object bean, String name) throws BeansException: Der erste Parameter dieser Methode ist die Bean-Instanz, die vom System nachbearbeitet werden soll, und der zweite Parameter ist die Konfigurations-ID der Bean.
  2. Object postProcessAfterinitialization(Object bean, String name) throws BeansException: Der erste Parameter dieser Methode ist die Bean-Instanz, die vom System nachbearbeitet werden soll, und der zweite Parameter ist die Konfigurations-ID der Bean.

Sobald ein Bean-Post-Prozessor im Container registriert ist, startet er automatisch und arbeitet automatisch, wenn jede Bean im Container erstellt wird. Der Rückrufzeitpunkt der beiden Methoden des Bean-Post-Prozessors ist in der folgenden Abbildung dargestellt:

bean-post-process

Beachten Sie: Wenn SieBeanFactoryals Spring-Container verwenden, müssen Sie den Bean-Post-Prozessor manuell registrieren. Das Programm muss eine Bean-Post-Prozessor-Instanz erhalten und sie dann manuell registrieren.

BeanPostProcessor bp = (BeanPostProcessor)beanFactory.getBean("bp");
beanFactory.addBeanPostProcessor(bp);
Person p = (Person)beanFactory.getBean("person");

Container-Post-Prozessor

Der Bean-Post-Prozessor ist für die Verarbeitung aller Bean-Instanzen im Container verantwortlich, während der Container-Post-Prozessor für die Verarbeitung des Containers selbst verantwortlich ist. Der Container-Post-Prozessor muss dieBeanFactoryPostProcessorSchnittstelle implementieren und eine Methode der Schnittstelle implementieren.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)Der Methodenrumpf, der diese Methode implementiert, ist die Verarbeitung, die am Spring-Container durchgeführt wird. Diese Verarbeitung kann eine benutzerdefinierte Erweiterung des Spring-Containers sein, oder sie kann natürlich auch überhaupt keine Verarbeitung am Spring-Container vornehmen.

ähnlich wieBeanPostProcessor,ApplicationContextKann Container-Post-Prozessoren im Container automatisch erkennen und Container-Post-Prozessoren automatisch registrieren. Wenn jedochBeanFactoryals Spring-Container verwendet wird, muss man diesen Container-Post-Prozessor manuell zur Verarbeitung aufrufen.BeanFactoryContainers.

Springs "Zero Configuration"-Unterstützung

Suchen nach Bean-Klassen

Spring bietet die folgenden Annotationen, um Spring-Beans zu markieren:

  • @Component: Kennzeichnet eine gewöhnliche Spring-Bean-Klasse.
  • @Controller: Annotiert eine Controller-Komponentenklasse.
  • @Service: Annotiert eine Komponentenklasse für Geschäftslogik.
  • @Repository: Annotiert eine DAO-Komponentenklasse.

Nehmen Sie die folgende Konfiguration in der Spring-Konfigurationsdatei vor, um das automatisch zu scannende Paket anzugeben:

<context:component-scan base-package="edu.shu.spring.domain"/>

Abhängigkeiten mit @Resource konfigurieren

@ResourceBefindet sich injavax.annotationUnter dem Paket gelegen, stammt es aus der JavaEE-Spezifikation.Annotation, hat Spring dies direkt übernommenAnnotation, indem man dies verwendetAnnotationGeben Sie die Collaborator-Beans für das Ziel-Bean an. Verwenden Sie@Resourceund<property.../>Das ref-Attribut des Elements hat denselben Effekt.
@Resourcekann nicht nur Setter-Methoden annotieren, sondern auch direkt Instanzvariablen annotieren. Bei Verwendung von@ResourceDas Annotieren von Instanzvariablen wird sogar noch einfacher; in diesem Fall verwendet Spring direkt die Feldinjektion des JavaEE-Standards, und nicht einmal Setter-Methoden sind erforderlich.

Anpassen des Lebenszyklusverhaltens mit @PostConstruct und @PreDestroy

@PostConstructund@PreDestroySie befinden sich ebenfalls im Paket javax.annotation und sind zwei Annotationen aus der JavaEE-Spezifikation. Spring hat sie direkt übernommen, um das Lebenszyklusverhalten von Beans im Spring-Container anzupassen. Beide werden verwendet, um Methoden zu modifizieren, und erfordern keine Attribute. Die von der ersten modifizierte Methode ist die Initialisierungsmethode des Beans; die von der zweiten modifizierte Methode ist die Methode vor der Zerstörung des Beans.

Erweitertes Autowiring und präzises Wiring in Spring 4.0

Spring bietet@AutowiredAnnotation zur Angabe von Autowiring,@Autowiredkann Setter-Methoden, reguläre Methoden, Instanzvariablen, Konstruktoren und so weiter annotieren. Bei Verwendung von@AutowiredBeim Annotieren einer Setter-Methode wird standardmäßig die Autowiring-Strategie byType verwendet. Bei dieser Strategie gibt es häufig mehrere Kandidaten-Bean-Instanzen, die zum Autowiring-Typ passen, was Ausnahmen verursachen kann. Um präzises Autowiring zu erreichen, bietet Spring@QualifierAnnotation, durch deren Verwendung@Qualifier, ermöglicht es, die automatische Assembly anhand der Bean-ID durchzuführen.

Springs AOP

Warum AOP benötigt wird

AOP (Aspektorientierte Programmierung), auch bekannt als aspektorientierte Programmierung, hat sich als Ergänzung zur objektorientierten Programmierung zu einem relativ ausgereiften Programmieransatz entwickelt. Tatsächlich gibt es AOP noch nicht sehr lange. AOP und OOP ergänzen sich; die aspektorientierte Programmierung zerlegt den Programmausführungsprozess in verschiedene Aspekte.

AOP wird speziell verwendet, um querschnittliche Belange (cross-cutting concerns) zu behandeln, die über verschiedene Module (verschiedene Methoden) in einem System verteilt sind. In JavaEE-Anwendungen wird AOP häufig verwendet, um Dienste auf Systemebene mit querschnittlichen Eigenschaften zu behandeln, wie Transaktionsverwaltung, Sicherheitsprüfungen, Caching und Objektpoolverwaltung. AOP ist zu einer sehr verbreiteten Lösung geworden.

Verwenden von AspectJ zur Implementierung von AOP

AspectJ ist ein AOP-Framework basierend auf der Java-Sprache und bietet leistungsstarke AOP-Funktionalität. Viele andere AOP-Frameworks haben einige seiner Ideen übernommen oder adaptiert. Es besteht hauptsächlich aus zwei Teilen: Ein Teil definiert die Syntaxspezifikation zum Ausdrücken und Definieren von AOP-Programmierung. Mit dieser Syntaxspezifikation können querschnittliche Belange in der Java-Sprache bequem gelöst werden; der andere Teil ist der Werkzeugteil, einschließlich Compiler- und Debugging-Tools usw.

AOP-Implementierungen können in zwei Kategorien unterteilt werden:

  1. Statische AOP-Implementierung: Das AOP-Framework modifiziert das Programm während der Kompilierungsphase, d. h. es erweitert die Zielklasse und generiert eine statische AOP-Proxy-Klasse, vertreten durch AspectJ.
  2. Dynamische AOP-Implementierung: Das AOP-Framework generiert zur Laufzeit dynamisch AOP-Proxys, um Zielobjekte zu erweitern, vertreten durch Spring AOP.

Im Allgemeinen hat die statische AOP-Implementierung eine bessere Leistung, erfordert jedoch einen speziellen Compiler. Die dynamische AOP-Implementierung ist eine reine Java-Implementierung, daher benötigt sie keinen speziellen Compiler, aber ihre Leistung ist normalerweise etwas schlechter.

Grundlegende Konzepte von AOP

Einige Begriffe zur aspektorientierten Programmierung:

  • Aspekt: Ein Aspekt wird verwendet, um mehrere Advice zu organisieren, und Advice wird im Aspekt definiert.
  • Joinpoint: Ein eindeutiger Punkt während der Programmausführung, wie z. B. ein Methodenaufruf oder das Auslösen einer Ausnahme. In Spring AOP ist ein Joinpoint immer ein Methodenaufruf.
  • Advice: Erweiterte Verarbeitung, die vom AOP-Framework an bestimmten Pointcuts ausgeführt wird. Die Verarbeitung hat Typen wie "around", "before" und "after".
  • Pointcut: Ein Joinpoint, an dem erweiterte Verarbeitung eingefügt werden kann. Kurz gesagt, wenn ein Joinpoint festgelegte Anforderungen erfüllt, wird dem Joinpoint erweiterte Verarbeitung hinzugefügt, und dieser Joinpoint wird zu einem Pointcut.

Springs AOP-Unterstützung

AOP-Proxys in Spring werden vom IoC-Container von Spring generiert und verwaltet, und ihre Abhängigkeiten werden ebenfalls vom IoC-Container verwaltet.
Um es in der Anwendung zu verwenden@AspectJUm dies zu unterstützen, muss Spring drei Bibliotheken hinzufügen:

  • aspectjweaver.jar
  • aspectjrt.jar
  • aopalliance.jar

Und nehmen Sie die folgende Konfiguration in der Spring-Konfigurationsdatei vor:

<!--启动@AspectJ支持-->
<aop:aspectj-autoproxy/>

<!--指定自动搜索Bean组件、自动搜索切面类-->
<context:component-scan base-package="edu.shu.sprint.service">
    <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>

Quelle:http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring/