📜  Spring @Qualifier 注解与示例

📅  最后修改于: 2022-05-13 01:55:40.293000             🧑  作者: Mango

Spring @Qualifier 注解与示例

Spring 是最流行的Java EE 框架之一。它是一个开源轻量级框架,允许Java EE 7 开发人员构建简单、可靠且可扩展的企业应用程序。该框架主要侧重于提供各种方法来帮助您管理业务对象。与Java数据库连接 (JDBC)、JavaServer Pages (JSP) 和Java Servlet 等经典Java框架和应用程序编程接口 (API) 相比,它使 Web 应用程序的开发更加容易。该框架使用各种新技术,如面向方面编程 (AOP)、普通Java对象 (POJO) 和依赖注入 (DI) 来开发企业应用程序。现在谈论 Spring Annotation

Spring 中最重要的注解之一是 @Qualifier 注解,用于消除需要注入哪个 bean 的问题。让我们通过一个例子来理解这一行。

执行:

让我们首先了解@Autowired Annotation 的问题,然后我们将了解为什么要引入@Qualifier Annotation。所以首先让我们创建一个名为Human的类,并且 Human 类确实依赖于另一个名为Heart的类。

一个文件: 人类。Java

Java
public class Human {
    private Heart heart;
}


Java
public class Heart {
    public void pump() {
        System.out.println("Heart is Pumping");
    }
}


Java
// Java Program to Illustrate Injection of object of the
// Heart class inside the Human class using the @Autowired
// annotation
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
// Class
public class Human {
 
    private Heart heart;
 
    // Annotation
    @Autowired public void setHeart(Heart heart)
    {
        this.heart = heart;
    }
 
    // Method
    // Calling method of Heart class
    public void startPumping() { heart.pump(); }
}


XML


 
    
 
    
    
  


Java
// Java Program to Illustrate Application Class
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
// Application class
// Main class
public class Main {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating an new class path
        ApplicationContext context
            = new ClassPathXmlApplicationContext(
                "beans.xml");
        Human human
            = context.getBean("humanObject", Human.class);
        human.startPumping();
    }
}


XML


 
    
 
    
    
 
    
 


Java
// Java Program to Illustrate Modified Human Class
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
// Class
public class Human {
 
    private Heart heart;
 
    // Annotation
    @Autowired
    @Qualifier("humanHeart")
 
    // Setter
    public void setHeart(Heart heart)
    {
        this.heart = heart;
    }
 
    // Method
    public void startPumping() { heart.pump(); }
}


Java
// Java Program to Illustrate Modified Human Class
// Where we used these annotations before the dependency
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
// Class
public class Human {
 
    @Autowired @Qualifier("humanHeart") private Heart heart;
 
    // Method
    public void startPumping() { heart.pump(); }
}


B文件: 心。Java

这个类只有一个名为pump() 的简单方法。

Java

public class Heart {
    public void pump() {
        System.out.println("Heart is Pumping");
    }
}

现在我们要使用 @Autowired 注解将 Heart 类的对象注入到 Human 类中。所以对于这个东西,我们可以这样写代码

例子

Java

// Java Program to Illustrate Injection of object of the
// Heart class inside the Human class using the @Autowired
// annotation
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
// Class
public class Human {
 
    private Heart heart;
 
    // Annotation
    @Autowired public void setHeart(Heart heart)
    {
        this.heart = heart;
    }
 
    // Method
    // Calling method of Heart class
    public void startPumping() { heart.pump(); }
}

C文件: 豆类.xml
所以在beans.xml文件中,我们可以这样写代码

XML



 
    
 
    
    
  

D应用类

在主类中,我们可以编写类似这样的代码

Java

// Java Program to Illustrate Application Class
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
// Application class
// Main class
public class Main {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating an new class path
        ApplicationContext context
            = new ClassPathXmlApplicationContext(
                "beans.xml");
        Human human
            = context.getBean("humanObject", Human.class);
        human.startPumping();
    }
}

输出:

Heart is Pumping

输出说明

所以上面的代码执行得很好。现在让我们简单解释一下上面代码中发生的事情。因此,每当您在 Human 类的 setter 方法之前放置 @Autowired 注释时,这将通过使用Spring Autowiring 'byType'的机制将 Heart 类的对象自动装配到 Human 类中。

所以在我们上面的例子中,“byType”Spring Autowiring 机制发生了,heart 对象被注入到 Human 类中。但问题出在哪里?现在在beans.xml文件中,让我们创建 Heart 类的另一个 bean。我们可以像这样编写代码。现在我们修改后的beans.xml文件是

XML



 
    
 
    
    
 
    
 

这里我们有两个相同类的bean,一个是“humanHeart”,另一个是“octpusHeart”。所以在那种情况下,“byType”和“byName”Spring Autowiring 都会失败。因为同一类 Heart 有两个 bean,并且 id 与对象“heart”不匹配。因此,每当您要运行应用程序时,都会遇到以下异常。

这就是@Qualifier Annotation 发挥作用的地方。因此,每当“byType”和“byName” Spring Autowiring 都将失败时,我们可以在 setter 方法之前使用 @Qualifier 注解,并且可以在其中提及 bean id。例如,在 Human 类的情况下,我们需要“humanHeart” bean,因此我们可以在 @Qualifier Annotation 中提及该 bean。所以我们可以写这样的东西来解决这个错误。

示例:修改后的 Human.class 文件

Java

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'humanObject': Unsatisfied dependency expressed through method 'setHeart' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'Heart' available: expected single matching bean but found 2: humanHeart,octpusHeart
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:768)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:720)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413)

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'Heart' available: expected single matching bean but found 2: humanHeart,octpusHeart
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1358)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)

输出:

// Java Program to Illustrate Modified Human Class
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
// Class
public class Human {
 
    private Heart heart;
 
    // Annotation
    @Autowired
    @Qualifier("humanHeart")
 
    // Setter
    public void setHeart(Heart heart)
    {
        this.heart = heart;
    }
 
    // Method
    public void startPumping() { heart.pump(); }
}

一件更有趣的事情是我们还可以在依赖项之前使用这些注解。不需要任何 setter 方法。所以我们也可以写这样的东西。

Java

Heart is Pumping