zoukankan      html  css  js  c++  java
  • (004)spring容器报错expected single matching bean but found的原因及解放方法

      如果spring容器中存在某个类型的bean有多个,在根据类型获取bean的时候就会报expected single matching bean but found(期望匹配一个bean,但是发现多个)的错误,请看下面的实例。

      示例1:

      pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.edu.spring</groupId>
        <artifactId>spring</artifactId>
        <version>1.0.0</version>
    
        <name>spring</name>
        <!-- FIXME change it to the project's website -->
        <url>http://www.example.com</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
        
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.2.RELEASE</version>
            </dependency>
        </dependencies>
    
    </project>
    View Code

      User.java

    package com.edu.spring;
    
    import org.springframework.stereotype.Component;
    
    @Component("myUser")
    public class User {
    
    }
    View Code

      MyConfig.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyConfig {
        
        @Bean
        public User createUser(){
            return new User();
        }
    }
    View Code

      App.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    
    public class App 
    {
        public static void main( String[] args )
        {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(User.class,MyConfig.class);
            System.out.println(context.getBean(User.class));
            context.close();
        }
    }
    View Code

      运行结果如下:

      报错信息为:Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.edu.spring.User] is defined: expected single matching bean but found 2: myUser,createUser。

      现在用名字获取一下,发现这是两个bean,如下:

      App.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    
    public class App 
    {
        public static void main( String[] args )
        {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(User.class,MyConfig.class);
            System.out.println(context.getBean("myUser"));
            System.out.println(context.getBean("createUser"));
            context.close();
        }
    }
    View Code

      运行结果如下:

       使用getBeansOfType可以获取某个类型的所有bean对象,如下:

      App.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    
    public class App 
    {
        public static void main( String[] args )
        {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(User.class,MyConfig.class);
            System.out.println(context.getBean("myUser"));
            System.out.println(context.getBean("createUser"));
            System.out.println(context.getBeansOfType(User.class));
            context.close();
        }
    }
    View Code

      运行结果如下:

      示例2:

      User.java

    package com.edu.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component("myUser")
    public class User {
        
        @Autowired
        private UserService userService;
    
        public void show(){
            userService.show();
        }
    
    }
    View Code

      UserDao.java

    package com.edu.spring;
    
    import org.springframework.stereotype.Repository;
    
    @Repository
    public class UserDao {
    
        public void show(){
            System.out.println("--------------show()------------------");
        }
    }
    View Code

      UserService.java

    package com.edu.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        
        @Autowired
        private UserDao userDao;
    
        public void show(){
            userDao.show();
        }
        
    }
    View Code

      App.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    
    public class App 
    {
        public static void main( String[] args )
        {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(User.class,UserDao.class,UserService.class);
            System.out.println(context.getBean(UserService.class));
            System.out.println(context.getBean(UserDao.class));
            User user=context.getBean("myUser",User.class);
            user.show();
            context.close();
        }
    }
    View Code

       运行结果如下:

       可以看到,正常运行,不会报错,下面再创建一个UserDao的bean,并且纳入到spring容器中,程序会报错expected single matching bean but found,如下:

      MyConfig.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyConfig {
        
        @Bean
        public UserDao createUserDao(){
            return new UserDao();
        }
    }
    View Code

      App.java 第一行新添加了 MyConfig.class。

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    
    public class App 
    {
        public static void main( String[] args )
        {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(User.class,UserDao.class,UserService.class,MyConfig.class);
            System.out.println(context.getBean(UserService.class));
            System.out.println(context.getBean(UserDao.class));
            User user=context.getBean("myUser",User.class);
            user.show();
            context.close();
        }
    }
    View Code

      运行结果如下:

       报错原因是以下代码引起

    System.out.println(context.getBean(UserDao.class));
    View Code

       注意,UserService中@Autowired注入userDao不会报错,这里的对象userDao即为bean的名称,请看以下代码:

      App.java 去掉System.out.println(context.getBean(UserDao.class));程序不会报错

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    
    public class App 
    {
        public static void main( String[] args )
        {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(User.class,UserDao.class,UserService.class,MyConfig.class);
            System.out.println(context.getBean(UserService.class));
            //System.out.println(context.getBean(UserDao.class));
            User user=context.getBean("myUser",User.class);
            user.show();
            context.close();
        }
    }
    View Code

      运行结果如下:

       原因出在Autowired注解,Autowired是把spring容器中已经存在的bean注入(装配)到对象中,Autowired优先根据bean类型注入,如果该类型有一个bean,注入成功,如果有多个bean,则根据名字注入,注入bean的名字与属性的名字形同的bean,没有名字相同的会报expected single matching bean but found。

      UserService.java中属性为createUserDao或者userDao都不会报错。如下:

    package com.edu.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        
        @Autowired
        private UserDao createUserDao;
    
        public void show(){
            createUserDao.show();
        }
        
    }
    View Code

      但是换成别的属性会报expected single matching bean but found,如下:

      UserService.java

    package com.edu.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        
        @Autowired
        private UserDao ssss;
    
        public void show(){
            ssss.show();
        }
        
    }
    View Code

      App.java

    package com.edu.spring;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    
    public class App 
    {
        public static void main( String[] args )
        {
            AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(User.class,UserDao.class,UserService.class,MyConfig.class);
            System.out.println(context.getBean(UserService.class));
            //System.out.println(context.getBean(UserDao.class));
            User user=context.getBean("myUser",User.class);
            user.show();
            context.close();
        }
    }
    View Code

      运行结果如下:

       解决办法,Qualifier注解指定其中的一个bean,如下:

      UserService.java

    package com.edu.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        
        @Autowired
        @Qualifier("createUserDao")
    
        private UserDao ssss;
    
        public void show(){
            ssss.show();
        }
        
    }
    View Code

      运行结果如下:

       还有一种解决方法,在创建bean时用Primary注解,如下:

      在UserDao.java中添加@Primary

    package com.edu.spring;
    
    import org.springframework.context.annotation.Primary;
    import org.springframework.stereotype.Repository;
    
    @Repository
    @Primary
    public class UserDao {
    
        public void show(){
            System.out.println("--------------show()------------------");
        }
    }
    View Code

      或者在MyConfig.java中添加

    package com.edu.spring;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    
    @Configuration
    public class MyConfig {
        
        @Bean
        @Primary
        public UserDao createUserDao(){
            return new UserDao();
        }
    }
    View Code
  • 相关阅读:
    Jasmine入门
    最近面试js部分试题总结
    最近面试前端面试题整理(css部分)
    开发自己的类库
    关于FEer发展方向的思考
    工作那些事(八)工作的目标——《360周鸿祎在新员工入职培训上的讲话》读后感
    工作那些事(七)选择与被选择
    工作那些事(六)谈谈好的编程习惯的好处
    工作那些事(五)谈谈项目资料整理和积累
    工作那些事(四)大公司VS小公司
  • 原文地址:https://www.cnblogs.com/javasl/p/11783482.html
Copyright © 2011-2022 走看看