Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么是NoSuchBeanDefinitionException,如何修复它?_Java_Spring_Applicationcontext - Fatal编程技术网

Java 什么是NoSuchBeanDefinitionException,如何修复它?

Java 什么是NoSuchBeanDefinitionException,如何修复它?,java,spring,applicationcontext,Java,Spring,Applicationcontext,请解释以下关于春季无此类定义异常的内容: 这是什么意思 在什么条件下会抛出 我怎样才能预防它 这篇文章是关于在使用Spring的应用程序中出现的NoSuchBeanDefinitionException的综合性问答。 当一个BeanFactory被请求一个 它找不到一个定义。这可能指向一个不存在的问题 bean、非唯一bean或手动注册的单实例 没有关联的bean定义 A基本上是表示的抽象。它向您的应用程序在内部和外部公开bean。当它找不到或检索不到这些bean时,它会抛出一个NoSuc

请解释以下关于春季无此类定义异常的内容:

  • 这是什么意思
  • 在什么条件下会抛出
  • 我怎样才能预防它

这篇文章是关于在使用Spring的应用程序中出现的
NoSuchBeanDefinitionException
的综合性问答。

当一个
BeanFactory
被请求一个 它找不到一个定义。这可能指向一个不存在的问题 bean、非唯一bean或手动注册的单实例 没有关联的bean定义

A基本上是表示的抽象。它向您的应用程序在内部和外部公开bean。当它找不到或检索不到这些bean时,它会抛出一个
NoSuchBeanDefinitionException

下面是
BeanFactory
(或相关类)无法找到bean的简单原因,以及如何确保它能够找到


该bean不存在,未注册 在下面的例子中

@Configuration
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
        ctx.getBean(Foo.class);
    }
}

class Foo {}   
我们没有通过
@bean
方法、
@Component
扫描、XML定义或任何其他方式为类型
Foo
注册bean定义。因此,由
AnnotationConfigApplicationContext
管理的
BeanFactory
没有指示从何处获取由
getBean(Foo.class)
请求的bean。上面的片段抛出

线程“main”org.springframework.beans.factory.NoSuchBean定义异常中的异常: 没有定义[com.example.Foo]类型的限定bean 类似地,在尝试满足
@Autowired
依赖项时可能会引发异常。比如说,

@Configuration
@ComponentScan
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
    }
}

@Component
class Foo { @Autowired Bar bar; }
class Bar { }
@Bean(name = "mysql")
@Qualifier(value = "main")
public DataSource mysql() { return new MySQL(); }
这里,通过
@ComponentScan
Foo
注册bean定义。但是Spring对
Bar
一无所知。因此,在尝试自动连接
Foo
bean实例的
bar
字段时,它无法找到相应的bean。它抛出(嵌套在

由以下原因引起:org.springframework.beans.factory.noSuchBean定义异常:
没有为依赖项[com.example.Bar]找到类型为[com.example.Bar]的符合条件的bean:
至少需要1个符合此依赖项autowire候选项条件的bean。依赖项注释:{@org.springframework.beans.factory.annotation.Autowired(required=true)}
注册bean定义有多种方法

  • @Bean
    方法在
    @Configuration
    类中或
    在XML配置中
  • @Component
    (及其元注释,例如
    @Repository
    )通过
    @ComponentScan
    以XML格式
  • 手动通过
  • 通过BeanDefinitionRegistryPostProcessor手动执行
…还有更多

确保您期望的bean已正确注册

一个常见错误是多次注册bean,即为同一类型混合上述选项。例如,我可能有

@Component
public class Foo {}
以及一个带有

<context:component-scan base-packages="com.example" />
<bean name="eg-different-name" class="com.example.Foo />
而Java提供了注释

需要单个匹配bean,但找到2个(或更多) 有时,您需要为同一类型(或接口)使用多个bean。例如,您的应用程序可能使用两个数据库,一个MySQL实例和一个Oracle实例。在这种情况下,您将有两个
DataSource
bean来管理到每个bean的连接。对于(简化)示例,如下所示

@Configuration
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
        System.out.println(ctx.getBean(DataSource.class));
    }
    @Bean(name = "mysql")
    public DataSource mysql() { return new MySQL(); }
    @Bean(name = "oracle")
    public DataSource oracle() { return new Oracle(); }
}
interface DataSource{}
class MySQL implements DataSource {}
class Oracle implements DataSource {}
投掷

线程“main”org.springframework.beans.factory.NoniqueBeandDefinitionException中的异常: 未定义[com.example.DataSource]类型的合格bean: 应为单个匹配bean,但找到2:oracle、mysql 因为通过
@Bean
方法注册的两个Bean都满足的要求,即它们都实现了
数据源
。在本例中,Spring没有机制来区分这两者或区分它们的优先级。但这种机制是存在的

您可以使用和中所述的(及其在XML中的等效项)。有了这个变化

@Bean(name = "mysql")
@Primary
public DataSource mysql() { return new MySQL(); } 
前面的代码段不会抛出异常,而是返回
mysql
bean

您还可以使用
@Qualifier
(及其在XML中的等效项)对bean选择过程进行更多控制,如中所述。虽然
@Autowired
主要用于按类型自动连线,但
@Qualifier
允许按名称自动连线。比如说,

@Configuration
@ComponentScan
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
    }
}

@Component
class Foo { @Autowired Bar bar; }
class Bar { }
@Bean(name = "mysql")
@Qualifier(value = "main")
public DataSource mysql() { return new MySQL(); }
现在可以作为

@Qualifier("main") // or @Qualifier("mysql"), to use the bean name
private DataSource dataSource;
毫无疑问。这也是一种选择

使用错误的bean名称 正如注册bean有多种方法一样,命名bean也有多种方法

这个bean的名称,或者如果是复数,这个bean的别名。如果留下 未指定bean的名称是带注释方法的名称。 如果指定,将忽略方法名称

具有
id
属性来表示bean的唯一标识符,
name
可用于在(XML)id中创建一个或多个非法别名

而且它的元注释

该值可能表示对逻辑组件名称的建议,以 在自动检测到组件的情况下,将转换为SpringBean

如果未指定,则会自动为带注释的类型生成bean名称,通常是类型名称的小写版本。例如,
MyClassName
变成了
MyClassName
作为它的bean名。Bean名称区分大小写。还要注意,错误的名称/大小写通常出现在由字符串
@DependsOn(“my BeanName”)
或XML配置文件引用的bean中

如前所述,
@Qualifier
允许您向bean添加更多别名

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.getEnvironment().setActiveProfiles("StackOverflow"); ctx.register(Example.class); ctx.refresh();
@Configuration
@EnableAsync
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
        System.out.println(ctx.getBean(HttpClientImpl.class).getClass());
    }
}

interface HttpClient {
    void doGetAsync();
}

@Component
class HttpClientImpl implements HttpClient {
    @Async
    public void doGetAsync() {
        System.out.println(Thread.currentThread());
    }
}
ctx.getBean(HttpClient.class) // returns a dynamic class: com.example.$Proxy33
// or
@Autowired private HttpClient httpClient;
@Autowired
private MovieCatalog[] movieCatalogs;
@Autowired
private Map<String, MovieCatalog> movies;
@Bean
public List<Foo> fooList() {
    return Arrays.asList(new Foo());
}
@Autowired
private List<Foo> foos;
@Resource
private List<Foo> foos;
// or since 4.3
public Example(@Autowired List<Foo> foos) {}
@Bean
public Bar other(List<Foo> foos) {
    new Bar(foos);
}
@Bean
public Bar other(@Value("#{fooList}") List<Foo> foos) {
    new Bar(foos);
}