Spring @Autowired Annotation

Die Spring @Autowired Annotation wird für die automatische Dependency Injection verwendet. Das Spring Framework basiert auf Dependency Injection und wir injizieren die Klassenabhängigkeiten über die Spring Bean-Konfigurationsdatei.

Normalerweise geben wir die Bean-Konfigurationsdetails in der Spring Bean-Konfigurationsdatei an und spezifizieren auch die Beans, die in andere Beans mit dem ref-Attribut injiziert werden sollen. Aber das Spring Framework bietet auch Autowiring-Funktionen, bei denen wir die Details der Bean-Injektion nicht explizit angeben müssen. Es gibt verschiedene Möglichkeiten, wie wir ein Spring Bean autowiren können.

    1. Autowire byName: Bei dieser Art von Autowiring wird die Setter-Methode für die Dependency Injection verwendet. Außerdem sollte der Variablenname in der Klasse, in die wir die Abhängigkeit injizieren, und in der Spring Bean-Konfigurationsdatei gleich sein.
    2. Autowire byType: Bei dieser Art von Autowiring wird der Klassentyp verwendet. Es sollte daher nur ein Bean für diesen Typ in der Spring Bean-Konfigurationsdatei konfiguriert sein.
    3. Autowire by Constructor: Dies ist fast ähnlich wie Autowire byType, der einzige Unterschied besteht darin, dass der Konstruktor zur Injektion der Abhängigkeit verwendet wird.
    4. Autowire by Autodetect: Wenn Sie Spring 3.0 oder ältere Versionen verwenden, ist dies eine der verfügbaren Autowire-Optionen. Diese Option wurde für Autowire by Constructor oder byType verwendet, wie vom Spring Container bestimmt. Da wir bereits so viele Optionen haben, ist diese Option veraltet. Ich werde diese Option in diesem Tutorial nicht behandeln.
    5. @Autowired Annotation: Wir können die Spring @Autowired Annotation für das Spring Bean Autowiring verwenden. Die @Autowired Annotation kann auf Variablen und Methoden für Autowiring byType angewendet werden. Wir können auch die @Autowired Annotation auf den Konstruktor für konstruktorbasiertes Spring Autowiring anwenden. Damit die @Autowired Annotation funktioniert, müssen wir auch die anmerkungsbasierte Konfiguration in der Spring Bean-Konfigurationsdatei aktivieren. Dies kann durch das context:annotation-config-Element oder durch Definieren eines Beans des Typs org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor erfolgen.
    6. @Qualifier Annotation: Diese Annotation wird verwendet, um Konflikte bei der Bean-Zuordnung zu vermeiden, und wir müssen den Bean-Namen angeben, der für das Autowiring verwendet wird. Auf diese Weise können wir Probleme vermeiden, bei denen mehrere Beans für denselben Typ definiert sind. Diese Annotation funktioniert normalerweise mit der @Autowired Annotation. Für Konstruktoren mit mehreren Argumenten können wir diese Annotation mit den Argumentnamen in der Methode verwenden.

Standardmäßig ist das Spring Bean Autowiring ausgeschaltet. Der Standardwert für das Spring Bean Autowire ist „default“, was bedeutet, dass kein Autowiring durchgeführt wird. Der Autowire-Wert „no“ hat auch das gleiche Verhalten. Um die Verwendung von Spring Bean Autowiring zu demonstrieren, erstellen wir ein einfaches Spring Maven-Projekt.

Lassen Sie uns jede der Autowire-Optionen nacheinander betrachten. Dazu erstellen wir ein Model Bean und eine Serviceklasse, in die wir das Model Bean injizieren werden.

Spring @Autowired Annotation – Maven-Abhängigkeiten

Für das Spring Autowiring müssen wir keine zusätzlichen Abhängigkeiten hinzufügen. Unsere pom.xml-Datei enthält die Kernabhängigkeiten des Spring Frameworks und sieht wie folgt aus.

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework.samples</groupId>
    <artifactId>SpringBeanAutowiring</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>

        
        <java.version>1.6</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        
        <spring-framework.version>4.0.2.RELEASE</spring-framework.version>

        
        <logback.version>1.0.13</logback.version>
        <slf4j.version>1.7.5</slf4j.version>

    </properties>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>

    </dependencies>
</project>

Spring @Autowired Annotation – Model Bean

Lassen Sie uns ein einfaches Java Bean namens Employee erstellen. Dieses Bean wird eine einzelne Eigenschaft mit Getter- und Setter-Methoden haben. Wir werden diesen Eigenschaftswert in der Spring Bean-Konfigurationsdatei initialisieren.

package com.journaldev.spring.autowiring.model;

public class Employee {

    private String name;

    public String getName() {
        return name;
    }

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

Spring @Autowired Annotation – Serviceklasse

Lassen Sie uns unsere Serviceklasse erstellen, in die wir das Employee Bean durch Spring Autowiring injizieren werden.

package com.journaldev.spring.autowiring.service;

import com.journaldev.spring.autowiring.model.Employee;

public class EmployeeService {

    private Employee employee;

    // constructor is used for autowire by constructor
    public EmployeeService(Employee emp) {
        System.out.println("Autowiring by constructor used");
        this.employee = emp;
    }

    // default constructor to avoid BeanInstantiationException for autowire
    // byName or byType
    public EmployeeService() {
        System.out.println("Default Constructor used");
    }

    // used for autowire byName and byType
    public void setEmployee(Employee emp) {
        this.employee = emp;
    }

    public Employee getEmployee() {
        return this.employee;
    }
}

Wir werden dieselbe Serviceklasse verwenden, um das Spring Autowiring byName, byType und by Constructor durchzuführen. Die Setter-Methode wird für das Spring Autowiring byName und byType verwendet, während die injektionsbasierte Injektion durch den Konstruktor-Autowire-Attribut verwendet wird. Wenn wir Spring Autowire byName oder byType verwenden, wird der Standardkonstruktor verwendet. Deshalb haben wir den Standardkonstruktor für das EmployeeService Bean explizit definiert.

Spring @Autowired Annotation – Autowiring byType Beispiel

Lassen Sie uns eine separate Klasse mit der Spring @Autowired Annotation für Autowiring byType erstellen.

package com.journaldev.spring.autowiring.service;

import org.springframework.beans.factory.annotation.Autowired;

import com.journaldev.spring.autowiring.model.Employee;

public class EmployeeAutowiredByTypeService {

    //Autowired annotation on variable/setters is equivalent to autowire="byType"
    @Autowired
    private Employee employee;
    
    @Autowired
    public void setEmployee(Employee emp){
        this.employee=emp;
    }
    
    public Employee getEmployee(){
        return this.employee;
    }
}

Beachten Sie, dass ich sowohl die Employee-Variable als auch deren Setter-Methode mit der Spring @Autowired Annotation annotiert habe, jedoch ist nur eine davon ausreichend für das Spring Bean Autowiring.

Spring @Autowired Annotation und @Qualifier – Autowiring by Constructor Beispiel

Lassen Sie uns eine weitere Serviceklasse erstellen, in der wir die @Autowired Annotation für die konstruktorbasierte Injektion verwenden werden. Wir werden auch die Verwendung der @Qualifier Annotation sehen.

package com.journaldev.spring.autowiring.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.journaldev.spring.autowiring.model.Employee;

public class EmployeeAutowiredByConstructorService {

    private Employee employee;

    //Autowired annotation on Constructor is equivalent to autowire="constructor"
    @Autowired(required=false)
    public EmployeeAutowiredByConstructorService(@Qualifier("employee") Employee emp){
        this.employee=emp;
    }
    
    public Employee getEmployee() {
        return this.employee;
    }
}

Wenn dieses Bean vom Spring Framework initialisiert wird, wird ein Bean mit dem Namen „employee“ für das Autowiring verwendet. Die Spring @Autowired Annotation akzeptiert ein Argument „required“, das ein Boolean mit dem Standardwert TRUE ist. Wir können es auf „false“ definieren, damit das Spring Framework keine Ausnahme wirft, wenn kein geeignetes Bean für das Autowiring gefunden wird.

Spring @Autowired Annotation – Bean-Konfigurationsdatei

Die Spring Bean-Konfigurationsdatei ist der Hauptteil jeder Spring-Anwendung, lassen Sie uns sehen, wie unsere Spring Bean-Konfigurationsdatei aussieht und dann werden wir jeden Teil davon betrachten.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="https://www.springframework.org/schema/context"
    xsi:schemaLocation="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-4.0.xsd"
        
        default-autowire="byName" default-autowire-candidates="*" >

<bean name="employee" class="com.journaldev.spring.autowiring.model.Employee">
    <property name="name" value="Pankaj"></property>
</bean>

<bean name="employee1" class="com.journaldev.spring.autowiring.model.Employee" autowire-candidate="false">
    <property name="name" value="Dummy Name"></property>
</bean>

<!-- autowiring byName, bean name should be same as the property name -->
<bean name="employeeServiceByName" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="byName" />

<!-- autowiring byType, there should be only one bean definition for the mapping -->
<bean name="employeeServiceByType" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="byType" />

<!-- autowiring by constructor -->
<bean name="employeeServiceConstructor" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="constructor" />

<!-- Enable Annotation based configuration -->
<context:annotation-config />

<!-- using @Autowiring annotation in below beans, byType and constructor -->
<bean name="employeeAutowiredByTypeService" class="com.journaldev.spring.autowiring.service.EmployeeAutowiredByTypeService" />
<bean name="employeeAutowiredByConstructorService" class="com.journaldev.spring.autowiring.service.EmployeeAutowiredByConstructorService" />
</beans>

Wichtige Punkte zur Spring Bean-Konfigurationsdatei

      • Das beans-Element default-autowire wird verwendet, um die Standardmethode für das Autowiring zu definieren. Hier definiere ich die Standardmethode für das Autowiring als byName.
      • Das beans-Element default-autowire-candidates wird verwendet, um das Muster für Bean-Namen bereitzustellen, die für das Autowiring verwendet werden können. Zur Vereinfachung erlaube ich, dass alle Bean-Definitionen für das Autowiring geeignet sind, jedoch können wir ein Muster für das Autowiring definieren.
      • autowire-candidate=“false“ wird in einer Bean-Definition verwendet, um sie für das Autowiring ungeeignet zu machen. Es ist nützlich, wenn wir mehrere Bean-Definitionen für einen einzelnen Typ haben und einige davon nicht autowired werden sollen.
      • Das Autowire-Attribut byName, byType und Konstruktor ist selbsterklärend, es gibt nicht viel zu erklären.
      • context:annotation-config wird verwendet, um die anmerkungsbasierte Konfigurationsunterstützung zu aktivieren. Beachten Sie, dass die Beans employeeAutowiredByTypeService und employeeAutowiredByConstructorService keine Autowire-Attribute haben.

Spring @Autowired Annotation – Testprogramm

Jetzt, da unsere Spring-Anwendung mit allen Arten von Spring Autowiring bereit ist, schreiben wir ein einfaches Testprogramm, um zu sehen, ob es wie erwartet funktioniert oder nicht.

package com.journaldev.spring.autowiring.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.journaldev.spring.autowiring.service.EmployeeAutowiredByConstructorService;
import com.journaldev.spring.autowiring.service.EmployeeAutowiredByTypeService;
import com.journaldev.spring.autowiring.service.EmployeeService;

public class SpringMain {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
		
		EmployeeService serviceByName = ctx.getBean("employeeServiceByName", EmployeeService.class);
		
		System.out.println("Autowiring byName. Employee Name="+serviceByName.getEmployee().getName());
		
		EmployeeService serviceByType = ctx.getBean("employeeServiceByType", EmployeeService.class);
		
		System.out.println("Autowiring byType. Employee Name="+serviceByType.getEmployee().getName());
		
		EmployeeService serviceByConstructor = ctx.getBean("employeeServiceConstructor", EmployeeService.class);
		
		System.out.println("Autowiring by Constructor. Employee Name="+serviceByConstructor.getEmployee().getName());
		
		//printing hashcode to confirm all the objects are of different type
		System.out.println(serviceByName.hashCode()+"::"+serviceByType.hashCode()+"::"+serviceByConstructor.hashCode());
		
		//Testing @Autowired annotations
		EmployeeAutowiredByTypeService autowiredByTypeService = ctx.getBean("employeeAutowiredByTypeService",EmployeeAutowiredByTypeService.class);
		
		System.out.println("@Autowired byType. Employee Name="+autowiredByTypeService.getEmployee().getName());

		EmployeeAutowiredByConstructorService autowiredByConstructorService = ctx.getBean("employeeAutowiredByConstructorService",EmployeeAutowiredByConstructorService.class);
		
		System.out.println("@Autowired by Constructor. Employee Name="+autowiredByConstructorService.getEmployee().getName());

		ctx.close();
	}
}

Das Programm ist einfach, wir erstellen nur den Spring-Anwendungskontext und verwenden ihn, um verschiedene Beans zu erhalten und den Namen des Mitarbeiters zu drucken. Wenn wir die obige Anwendung ausführen, erhalten wir die folgende Ausgabe.

Mar 31, 2014 10:41:58 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3fa99295: startup date [Mon Mar 31 22:41:58 PDT 2014]; root of context hierarchy
Mar 31, 2014 10:41:58 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Default Constructor used
Default Constructor used
Autowiring by constructor used
Autowiring byName. Employee Name=Pankaj
Autowiring byType. Employee Name=Pankaj
Autowiring by Constructor. Employee Name=Pankaj
21594592::15571401::1863015320
@Autowired byType. Employee Name=Pankaj
@Autowired by Constructor. Employee Name=Pankaj
Mar 31, 2014 10:41:58 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@3fa99295: startup date [Mon Mar 31 22:41:58 PDT 2014]; root of context hierarchy

Wie Sie sehen können, wird für Autowire byName und byType der Standardkonstruktor ohne Argumente verwendet, um das Bean zu initialisieren. Für Autowire by Constructor wird ein konstruktorbasierter Konstruktor verwendet. Anhand des Hashcodes aller Variablen haben wir bestätigt, dass alle Spring-Beans unterschiedliche Objekte sind und nicht auf dasselbe Objekt verweisen. Da wir „employee1″ aus der Liste der für das Autowiring geeigneten Beans entfernt haben, gab es keine Verwirrung bei der Bean-Zuordnung. Wenn wir autowire-candidate=“false“ aus der Definition von „employee1“ entfernen, erhalten wir die folgende Fehlermeldung, wenn wir die oben genannte Hauptmethode ausführen.

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'employeeServiceByType' defined in class path resource [spring.xml]: Unsatisfied dependency expressed through bean property 'employee': : No qualifying bean of type [com.journaldev.spring.autowiring.model.Employee] is defined: expected single matching bean but found 2: employee,employee1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.journaldev.spring.autowiring.model.Employee] is defined: expected single matching bean but found 2: employee,employee1
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1278)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1170)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
	at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
	at com.journaldev.spring.autowiring.main.SpringMain.main(SpringMain.java:12)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.journaldev.spring.autowiring.model.Employee] is defined: expected single matching bean but found 2: employee,employee1
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1263)
	... 13 more

Das ist alles zur Spring @Autowired Annotation und zur Spring Autowiring-Funktion.

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren: