Spring——@Autowire冲突问题

xiaoxiao2021-02-28  91

Spring——@Autowire冲突问题

spring中使用@Autowire实现依赖注入。在使用的时候需要注意的是,满足注入条件的bean有多个的时候需要添加标识来区分目前需要注入的是哪个bean。 好,下面上货: 1、新建一个maven项目 mvn archetype:generate -DarchetypeCatalog=internal 2、修改pom文件 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <springframework.version>4.3.7.RELEASE</springframework.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${springframework.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <archive> <manifest> <mainClass>com.xueyou.demo.App</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- bind to the packaging phase --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 3、先看一下类图: 4、Eat接口 package com.xueyou.demo2; public interface Eat { void eatMeal(); } EatImpl1 package com.xueyou.demo2; import org.springframework.stereotype.Component; @Component public class EatImpl1 implements Eat { @Override public void eatMeal() { System.out.println("this is eatImpl1"); } } EatImpl2 package com.xueyou.demo2; import org.springframework.stereotype.Component; @Component public class EatImpl2 implements Eat{ @Override public void eatMeal() { System.out.println("this is eatImpl2"); } } EatImpl3 package com.xueyou.demo2; import org.springframework.stereotype.Component; @Component public class EatImpl3 implements Eat{ @Override public void eatMeal() { System.out.println("this is eatImpl3"); } } Animal package com.xueyou.demo2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class Animal { @Autowired private Eat eat; public void eatDetail() { eat.eatMeal(); } } App package com.xueyou.demo; import com.xueyou.demo2.Animal; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * Hello world! */ @Configuration @ComponentScan(basePackages = {"org.xueyou.demo","com.xueyou.demo","com.xueyou.demo2"}) public class App { public static void main(String[] args) { System.out.println("Hello World!"); ApplicationContext applicationContext = new AnnotationConfigApplicationContext(com.xueyou.demo.App.class); // Person p = applicationContext.getBean(Person.class); // p.showMyBody(); Animal animal = applicationContext.getBean(Animal.class); animal.eatDetail(); } } 5、运行结果: 从运行结果上能够看出,现在出现的错误是NoUniqueBeanDefinitionException。 原因是这样的在@Autowired注解进行自动装配的时候,发现有三个类都满足要求,这个时候spring不能够从这三个bean中选择一个bean进行装配,从而出现异常。 解决方法: 1、使用@Primary注解 2、使用@Qualifier注解 3、自定义注解 前两种方法比较简单,就是类似这样 package com.xueyou.demo2; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component @Qualifier("firstEat") public class EatImpl1 implements Eat { @Override public void eatMeal() { System.out.println("this is eatImpl1"); } } 然后在Animal使用的时候制定标志 package com.xueyou.demo2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class Animal { @Autowired @Qualifier("firstEat") private Eat eat; public void eatDetail() { eat.eatMeal(); } } 再次运行会发现已经可以了。 这里主要介绍一下自定义注解的方式: 首先要新建注解。 package com.xueyou.demo2; import org.springframework.beans.factory.annotation.Qualifier; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface EatAnno { String value() default ""; } 使用自定义注解。 package com.xueyou.demo2; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component @EatAnno(value = "firstEat") public class EatImpl1 implements Eat { @Override public void eatMeal() { System.out.println("this is eatImpl1"); } } package com.xueyou.demo2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class Animal { @Autowired @EatAnno(value = "firstEat") private Eat eat; public void eatDetail() { eat.eatMeal(); } } 运行结果:
转载请注明原文地址: https://www.6miu.com/read-83443.html

最新回复(0)