Spring IoC, Spring Bean Beispiel Tutorial

Willkommen zum Beispiel-Tutorial für den Spring IoC. Das Spring Framework basiert auf dem Prinzip der Inversion of Control. Dependency Injection ist die Technik zur Umsetzung von IoC in Anwendungen.

Spring IoC

Heute werden wir uns den Spring IoC Container ansehen. Wir werden auch Spring Bean durchgehen. Unten finden Sie das Inhaltsverzeichnis für eine schnelle Navigation zu verschiedenen Abschnitten des Spring IoC-Tutorials.

  1. Spring IoC
  2. Spring Bean
  3. Spring Bean Scopes
  4. Spring Bean Configuration
  5. Spring IoC und Spring Bean Beispiel
    1. XML-basierte Spring Bean-Konfiguration
    2. Annotation-basierte Spring Bean-Konfiguration
    3. Java-basierte Spring Bean-Konfiguration

Spring IoC-Container

Spring IoC ist der Mechanismus, um eine schwache Kopplung zwischen Objektabhängigkeiten zu erreichen. Um eine schwache Kopplung und eine dynamische Bindung der Objekte zur Laufzeit zu erreichen, werden Objektabhängigkeiten von anderen Assemblerobjekten injiziert. Der Spring IoC-Container ist das Programm, das Abhängigkeiten in ein Objekt injiziert und es für unsere Verwendung bereit macht. Wir haben bereits gesehen, wie wir Spring Dependency Injection verwenden können, um IoC in unseren Anwendungen zu implementieren. Die Klassen des Spring IoC-Containers sind Teil der Pakete org.springframework.beans und org.springframework.context. Der Spring IoC-Container bietet uns verschiedene Möglichkeiten, die Abhängigkeiten der Objekte zu entkoppeln. Die Schnittstelle BeanFactory ist die Wurzelschnittstelle des Spring IoC-Containers. Die Schnittstelle ApplicationContext ist die Unterklasse der Schnittstelle BeanFactory, die Spring AOP-Funktionen, i18n usw. bereitstellt. Einige nützliche Unterinterfaces von ApplicationContext sind ConfigurableApplicationContext und WebApplicationContext. Das Spring Framework bietet eine Reihe nützlicher Implementierungsklassen von ApplicationContext, die wir verwenden können, um den Spring-Kontext und dann das Spring Bean zu erhalten. Einige nützliche Implementierungen von ApplicationContext, die wir verwenden, sind;

  • AnnotationConfigApplicationContext: Wenn wir Spring in eigenständigen Java-Anwendungen verwenden und Annotationen für die Konfiguration verwenden, können wir dies verwenden, um den Container zu initialisieren und die Bean-Objekte zu erhalten.
  • ClassPathXmlApplicationContext: Wenn wir eine Spring Bean-Konfigurations-XML-Datei in einer eigenständigen Anwendung haben, können wir diese Klasse verwenden, um die Datei zu laden und das Containerobjekt zu erhalten.
  • FileSystemXmlApplicationContext: Dies ist ähnlich wie ClassPathXmlApplicationContext, außer dass die XML-Konfigurationsdatei aus jedem beliebigen Ort im Dateisystem geladen werden kann.
  • AnnotationConfigWebApplicationContext und XmlWebApplicationContext für Webanwendungen.

Normalerweise wird der Spring IoC-Container initialisiert, wenn die Anwendung startet und wenn eine Bean angefordert wird, werden die Abhängigkeiten automatisch injiziert, wenn Sie an einer Spring MVC-Anwendung arbeiten und Ihre Anwendung so konfiguriert ist, dass sie das Spring-Framework verwendet. Für eine eigenständige Anwendung müssen Sie jedoch den Container irgendwo in der Anwendung initialisieren und ihn dann verwenden, um die Spring-Beans zu erhalten.

Spring Bean

Spring Bean ist nichts Besonderes, jedes Objekt im Spring-Framework, das wir über den Spring-Container initialisieren, wird als Spring Bean bezeichnet. Jede normale Java-POJO-Klasse kann eine Spring Bean sein, wenn sie so konfiguriert ist, dass sie über Metadateninformationen initialisiert wird.

Spring Bean Scopes

Es gibt fünf Bereiche, die für Spring Beans definiert sind.

  1. singleton – Es wird nur eine Instanz des Beans für jeden Container erstellt. Dies ist der Standardbereich für die Spring Beans. Beim Verwenden dieses Bereichs stellen Sie sicher, dass das Bean keine gemeinsam genutzten Instanzvariablen hat, da dies zu Dateninkonsistenzproblemen führen kann.
  2. prototype – Eine neue Instanz wird jedes Mal erstellt, wenn das Bean angefordert wird.
  3. request – Dies entspricht dem Bereich prototype, ist jedoch für Webanwendungen gedacht. Für jede HTTP-Anforderung wird eine neue Instanz des Beans erstellt.
  4. session – Für jede HTTP-Sitzung wird vom Container ein neues Bean erstellt.
  5. global-session – Dies wird verwendet, um globale Sitzungsbeans für Portlet-Anwendungen zu erstellen.

Das Spring Framework ist erweiterbar, und wir können auch unsere eigenen Bereiche erstellen. In den meisten Fällen sind wir jedoch mit den vom Framework bereitgestellten Bereichen zufrieden.

Spring Bean-Konfiguration

Das Spring Framework bietet drei Möglichkeiten, Beans zu konfigurieren, die in der Anwendung verwendet werden sollen.

  1. Annotation Based Configuration – Durch Verwendung von @Service oder @Component Annotationen. Detailinformationen zum Umfang können mit der @Scope Annotation bereitgestellt werden.
  2. XML-basierte Konfiguration – Durch Erstellen einer Spring-Konfigurationsdatei in XML, um die Beans zu konfigurieren. Wenn Sie das Spring MVC-Framework verwenden, kann die XML-basierte Konfiguration automatisch geladen werden, indem Sie einige Vorlagen im web.xml-Datei schreiben.
  3. Java-basierte Konfiguration – Ab Spring 3.0 können wir Spring-Beans mithilfe von Java-Programmen konfigurieren. Einige wichtige Annotationen für die java-basierte Konfiguration sind @Configuration, @ComponentScan und @Bean.

Spring IoC und Spring Bean Beispielprojekt

Lassen Sie uns die verschiedenen Aspekte des Spring IoC-Containers und der Spring Bean-Konfigurationen mit einem einfachen Spring-Projekt betrachten. Für mein Beispiel erstelle ich ein Spring MVC-Projekt in der Spring Tool Suite. Wenn Sie neu bei Spring Tool Suite und Spring MVC sind, lesen Sie bitte die Spring MVC-Anleitung mit Spring Tool Suite. Die finale Projektstruktur sieht wie im folgenden Bild aus. Lassen Sie uns die verschiedenen Komponenten des Spring IoC- und Spring Bean-Projekts nacheinander betrachten.

XML-basierte Spring Bean-Konfiguration

MyBean ist eine einfache Java-POJO-Klasse.

package com.journaldev.spring.beans;

public class MyBean {

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

Spring-Konfigurations-XML-Datei

servlet-context.xml-Code:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="https://www.springframework.org/schema/beans"
	xmlns:context="https://www.springframework.org/schema/context"
	xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.journaldev.spring" />
	
	<beans:bean name="myBean" class="com.journaldev.spring.beans.MyBean" scope="singleton" ></beans:bean>
	
</beans:beans>

Beachten Sie, dass MyBean mithilfe des bean-Elements mit dem Umfang als Singleton konfiguriert ist.

Annotation-basierte Spring-Bean-Konfiguration

package com.journaldev.spring.beans;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.web.context.WebApplicationContext;

@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class MyAnnotatedBean {

	private int empId;

	public int getEmpId() {
		return empId;
	}

	public void setEmpId(int empId) {
		this.empId = empId;
	}
	
}

MyAnnotatedBean ist konfiguriert mit @Service und der Bereich ist auf Anfrage eingestellt.

Spring IoC Controller-Klasse

Die HomeController-Klasse wird die HTTP-Anfragen für die Startseite der Anwendung verarbeiten. Wir werden unsere Spring-Beans in diese Controller-Klasse über den WebApplicationContext-Container injizieren.

package com.journaldev.spring.controller;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.journaldev.spring.beans.MyAnnotatedBean;
import com.journaldev.spring.beans.MyBean;

@Controller
@Scope("request")
public class HomeController {
		
	private MyBean myBean;
	
	private MyAnnotatedBean myAnnotatedBean;

	@Autowired
	public void setMyBean(MyBean myBean) {
		this.myBean = myBean;
	}

	@Autowired
	public void setMyAnnotatedBean(MyAnnotatedBean obj) {
		this.myAnnotatedBean = obj;
	}
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		System.out.println("MyBean hashcode="+myBean.hashCode());
		System.out.println("MyAnnotatedBean hashcode="+myAnnotatedBean.hashCode());
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}

Bereitstellungsbeschreibung

Wir müssen unsere Anwendung für das Spring Framework konfigurieren, damit die Konfigurationsmetadaten geladen und der Kontext initialisiert werden.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

Fast die gesamte oben genannte Konfiguration ist Boilerplate-Code, der automatisch vom STS-Tool generiert wird.

Führen Sie die Beispielanwendung für Spring IoC Beans aus

Wenn Sie jetzt die Webanwendung starten, wird die Startseite geladen und in der Konsole werden beim Aktualisieren der Seite mehrmals folgende Protokolle gedruckt.

MyBean hashcode=118267258
MyAnnotatedBean hashcode=1703899856
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1115599742
MyBean hashcode=118267258
MyAnnotatedBean hashcode=516457106

Beachten Sie, dass MyBean so konfiguriert ist, dass es ein Singleton ist. Daher gibt der Container immer dieselbe Instanz zurück, und der Hashcode ist immer gleich. Ähnlich wird für jede Anfrage eine neue Instanz von MyAnnotatedBean mit unterschiedlichem Hashcode erstellt.

Java-basierte Frühlingsbohnenkonfiguration

Für eigenständige Anwendungen können wir sowohl eine annotationsbasierte als auch eine XML-basierte Konfiguration verwenden. Die einzige Voraussetzung ist, den Kontext irgendwo im Programm zu initialisieren, bevor wir ihn verwenden.

package com.journaldev.spring.main;

import java.util.Date;

public class MyService {

	public void log(String msg){
		System.out.println(new Date()+"::"+msg);
	}
}

MyService ist eine einfache Java-Klasse mit einigen Methoden.

package com.journaldev.spring.main;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value="com.journaldev.spring.main")
public class MyConfiguration {

	@Bean
	public MyService getService(){
		return new MyService();
	}
}

Die annotationsbasierte Konfigurationsklasse, die verwendet wird, um den Spring-Container zu initialisieren.

package com.journaldev.spring.main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyMainClass {

	public static void main(String[] args) {
		
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
				MyConfiguration.class);
		MyService service = ctx.getBean(MyService.class);
		
		service.log("Hi");
		
		MyService newService = ctx.getBean(MyService.class);
		System.out.println("service hashcode="+service.hashCode());
		System.out.println("newService hashcode="+newService.hashCode());
		ctx.close();
	}

}

A simple test program where we are initializing the AnnotationConfigApplicationContext context and then using getBean() method to get the instance of MyService. Notice that I am calling getBean method two times and printing the hashcode. Since there is no scope defined for MyService, it should be a singleton and hence hashcode should be the same for both the instances. When we run the above application, we get following console output confirming our understanding.

Sat Dec 28 22:49:18 PST 2013::Hi
service hashcode=678984726
newService hashcode=678984726

Wenn Sie nach einer XML-basierten Konfiguration suchen, erstellen Sie einfach die Spring XML-Konfigurationsdatei und initialisieren Sie dann den Kontext mit folgendem Code-Snippet.

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        MyService app = context.getBean(MyService.class);

Das ist alles für das Beispiel-Tutorial zu Spring IoC, Spring Bean Scopes und Konfigurationsdetails. Laden Sie das Spring IoC- und Spring Bean-Beispielprojekt über den unten stehenden Link herunter und experimentieren Sie damit, um es besser zu verstehen.

Spring-Bohnenprojekt herunterladen

Referenz: Spring.IO-Seite für IOC

Source:
https://www.digitalocean.com/community/tutorials/spring-ioc-bean-example-tutorial