Spring——@Autowire冲突问题

来源:互联网 发布:在贵州吃腊肉 知乎 编辑:程序博客网 时间:2024/04/25 23:15

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;@Componentpublic class EatImpl1 implements Eat {    @Override    public void eatMeal() {        System.out.println("this is eatImpl1");    }}

EatImpl2
package com.xueyou.demo2;import org.springframework.stereotype.Component;@Componentpublic class EatImpl2 implements Eat{    @Override    public void eatMeal() {        System.out.println("this is eatImpl2");    }}

EatImpl3
package com.xueyou.demo2;import org.springframework.stereotype.Component;@Componentpublic 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;@Componentpublic 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;@Componentpublic 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)@Qualifierpublic @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;@Componentpublic class Animal {    @Autowired    @EatAnno(value = "firstEat")    private Eat eat;    public void eatDetail() {        eat.eatMeal();    }}

运行结果:


0 0
原创粉丝点击