- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请解释以下有关 Spring 中 NoSuchBeanDefinitionException
异常的信息:
NoSuchBeanDefinitionException
进行全面的问答。
最佳答案
javadoc of NoSuchBeanDefinitionException
解释
Exception thrown when a
BeanFactory
is asked for a bean instance forwhich it cannot find a definition. This may point to a non-existingbean, a non-unique bean, or a manually registered singleton instancewithout an associated bean definition.
BeanFactory
基本上是代表
Spring's Inversion of Control container 的抽象。它在内部和外部向您的应用程序公开 bean。当它无法找到或检索这些 bean 时,它会抛出
NoSuchBeanDefinitionException
。
BeanFactory
(或相关类)无法找到 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 {}
我们还没有通过
Foo
方法、
@Bean
扫描、XML 定义或任何其他方式为
@Component
类型注册 bean 定义。因此,由
BeanFactory
管理的
AnnotationConfigApplicationContext
没有指示从何处获取
getBean(Foo.class)
请求的 bean。上面的片段抛出
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.example.Foo] is defined
类似地,在尝试满足
@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 { }
在这里,为
Foo
到
@ComponentScan
注册了一个 bean 定义。但是 Spring 对
Bar
一无所知。因此,在尝试 Autowiring
bar
bean 实例的
Foo
字段时,它无法找到相应的 bean。它抛出(嵌套在
UnsatisfiedDependencyException
内)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.example.Bar] found for dependency [com.example.Bar]:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
有多种方法可以注册 bean 定义。
@Bean
类中的方法 @Configuration
或 XML 配置中的 <bean>
@Component
(及其元注释,例如 @Repository
)至 @ComponentScan
或 0x251843141 中的 0x25181223134319 XML2319 2319 19 231212124124<context:component-scan ... />
GenericApplicationContext#registerBeanDefinition
@Component
public class Foo {}
和一个 XML 配置
<context:component-scan base-packages="com.example" />
<bean name="eg-different-name" class="com.example.Foo />
这样的配置将注册两个类型为
BeanDefinitionRegistryPostProcessor
的 bean,一个名称为
Foo
,另一个名称为
foo
。确保您不会意外注册比您想要的更多的 bean。这导致我们...
<import resource=""/>
而 Java 提供了
eg-different-name
注释。
@ImportResource
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 {}
throw
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [com.example.DataSource] is defined:
expected single matching bean but found 2: oracle,mysql
因为通过
DataSource
方法注册的两个 bean 都满足
@Bean
的要求,即。他们都实现了
BeanFactory#getBean(Class)
。在这个例子中,Spring 没有机制来区分或优先考虑两者。但是这样的机制是存在的。
DataSource
(及其在 XML 中的等效项),如
documentation 和
this post 中所述。有了这个变化
@Bean(name = "mysql")
@Primary
public DataSource mysql() { return new MySQL(); }
前面的代码片段不会抛出异常,而是返回
@Primary
bean。
mysql
(及其在 XML 中的等效项)来更好地控制 bean 选择过程,如
documentation 中所述。虽然
@Qualifier
主要用于按类型 Autowiring ,但
@Autowired
可让您按名称 Autowiring 。例如,
@Bean(name = "mysql")
@Qualifier(value = "main")
public DataSource mysql() { return new MySQL(); }
现在可以注入(inject)为
@Qualifier("main") // or @Qualifier("mysql"), to use the bean name
private DataSource dataSource;
没有问题。
@Qualifier
也是一个选项。
@Resource
有
@Bean
The name of this bean, or if plural, aliases for this bean. If leftunspecified the name of the bean is the name of the annotated method.If specified, the method name is ignored.
name
具有
<bean>
属性来表示 bean 的唯一标识符,
id
可用于在 (XML) id 中创建一个或多个非法别名。
name
及其元注释有
@Component
The value may indicate a suggestion for a logical component name, tobe turned into a Spring bean in case of an autodetected component.
value
变为
MyClassName
作为其 bean 名称。 Bean 名称区分大小写。另请注意,错误的名称/大写通常出现在由
myClassName
或 XML 配置文件等字符串引用的 bean 中。
@DependsOn("my BeanName")
允许您向 bean 添加更多别名。
@Qualifier
,具体来说,
Indicates that a component is eligible for registration when one ormore specified profiles are active.
A profile is a named logical grouping that may be activatedprogrammatically via
ConfigurableEnvironment.setActiveProfiles(java.lang.String...)
ordeclaratively by setting thespring.profiles.active
property as a JVMsystem property, as an environment variable, or as a Servlet contextparameter in web.xml for web applications. Profiles may also beactivated declaratively in integration tests via the@ActiveProfiles
annotation.
@Profile
属性的示例。
@Configuration
@ComponentScan
public class Example {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
System.out.println(Arrays.toString(ctx.getEnvironment().getActiveProfiles()));
System.out.println(ctx.getBean(Foo.class));
}
}
@Profile(value = "StackOverflow")
@Component
class Foo {
}
这将显示没有 Activity 的配置文件,并为
spring.profiles.active
bean 抛出
NoSuchBeanDefinitionException
。由于
Foo
配置文件未处于 Activity 状态,因此该 bean 未注册。
StackOverflow
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("StackOverflow");
ctx.register(Example.class);
ctx.refresh();
bean 已注册并可返回/注入(inject)。
ApplicationContext
@Transactional
@Cacheable
和 @Async
@Scheduled
的默认值 @EnableAsync
的 proxyTargetClass
实现)@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());
}
}
在这里,Spring 试图找到一个类型为 false
的 bean,我们希望找到它,因为该类型清楚地用 HttpClientImpl
进行了注释。然而,相反,我们得到了一个异常(exception)Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.example.HttpClientImpl] is defined
Spring 包裹了 @Component
bean 并通过一个仅实现 HttpClientImpl
的 Proxy
对象暴露它。所以你可以用ctx.getBean(HttpClient.class) // returns a dynamic class: com.example.$Proxy33
// or
@Autowired private HttpClient httpClient;
始终建议使用 program to interfaces 。如果不能,您可以告诉 Spring 使用 CGLIB 代理。例如,对于 HttpClient
,您可以将 @EnableAsync
设置为 proxyTargetClass
。类似的注释( true
等)具有类似的属性。 XML 也将具有等效的配置选项。EnableTransactionManagement
层次结构-Spring MVCApplicationContext
构建 ApplicationContext
实例,其他 ApplicationContext
实例作为父实例。子上下文可以访问父上下文中的 bean,但反之则不然。 This post 详细介绍了这何时有用,尤其是在 Spring MVC 中。ConfigurableApplicationContext#setParent(ApplicationContext)
(路由、处理程序方法、 Controller )。您可以在此处获得更多详细信息:DispatcherServlet
注解@EnableWebMvc
类或在XML @Configuration
,但 <mvc:annotation-driven />
bean 在servlet上下文声明在根上下文的WebMVC配置。 由于根上下文无法进入 servlet 上下文以找到任何 bean,因此没有注册处理程序并且所有请求都以 404 失败。 你不会看到 @Controller
,但效果是一样的。NoSuchBeanDefinitionException
、 HandlerMapping
、 HandlerAdapter
、 ViewResolver
等)。最好的解决方案是正确隔离bean。 ExceptionResolver
负责路由和处理请求,因此所有相关的 bean 都应该进入其上下文。加载根上下文的 DispatcherServlet
应该初始化应用程序其余部分所需的任何 bean:服务、存储库等。ContextLoaderListener
的数组注入(inject)到字段中@Autowired
private MovieCatalog[] movieCatalogs;
Spring 将找到所有 MovieCatalog
类型的 bean,将它们包装在一个数组中,然后注入(inject)该数组。这在 Spring documentation discussing MovieCatalog
中有描述。类似的行为适用于 @Autowired
、 Set
和 List
注入(inject)目标。Collection
注入(inject)目标,如果键类型为 Map
,Spring 也会以这种方式运行。例如,如果你有@Autowired
private Map<String, MovieCatalog> movies;
Spring 将找到所有类型为 String
的 bean,并将它们作为值添加到 MovieCatalog
中,其中相应的键将是它们的 bean 名称。Map
。但是,有时您只想声明这些集合类型的 bean,例如@Bean
public List<Foo> fooList() {
return Arrays.asList(new Foo());
}
并注入(inject)它们@Autowired
private List<Foo> foos;
在此示例中,Spring 将失败并返回 NoSuchBeanDefinitionException
,因为您的上下文中没有 NoSuchBeanDefinitionException
bean。但是你不想要一个 Foo
bean,你想要一个 Foo
bean。 Before Spring 4.3, you'd have to use List<Foo>
For beans that are themselves defined as a collection/map or arraytype,
@Resource
is a fine solution, referring to the specificcollection or array bean by unique name. That said, as of 4.3,collection/map and array types can be matched through Spring’s@Autowired
type matching algorithm as well, as long as the elementtype information is preserved in@Bean
return type signatures orcollection inheritance hierarchies. In this case, qualifier values canbe used to select among same-typed collections, as outlined in theprevious paragraph.
@Resource
private List<Foo> foos;
// or since 4.3
public Example(@Autowired List<Foo> foos) {}
但是,对于 @Resource
方法,即会失败。@Bean
public Bar other(List<Foo> foos) {
new Bar(foos);
}
在这里,Spring 忽略任何 @Bean
或 @Resource
注释该方法,因为它是 @Autowired
方法,因此不能应用文档中描述的行为。但是,您可以使用 Spring 表达式语言 (SpEL) 通过名称来引用 bean。在上面的例子中,你可以使用@Bean
public Bar other(@Value("#{fooList}") List<Foo> foos) {
new Bar(foos);
}
引用名为 @Bean
的 bean 并注入(inject)它。
关于java - 什么是 NoSuchBeanDefinitionException 以及如何修复它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39173982/
我正在获取 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring
我创建了一个库,用于在多个 Spring Boot 应用程序上共享代码。 该库包含一个 Repository 类 RequestRepository。将库添加到 Spring Boot 项目后,编译并
所以我尝试使用在另一个类中生成的 bean 以在主应用程序中使用 package com.simon.spring.basics.properties; import org.spri
我使用 spring-data-jpa。没有 Spring Boot。 package ru.spb.repository; public interface CrudUserRepository e
我尝试使用ClassPathXmlApplicationContext获取bean。但我收到:NoSuchBeanDefinitionException:未定义名为“newsController”的
请解释以下有关 Spring 中 NoSuchBeanDefinitionException 异常的信息: 是什么意思? 什么情况下会抛出? 我该如何预防? 这篇文章旨在对使用 Spring 的应用程
我刚刚使用 Spring Boot V1.3.5 设置了一个新项目,在尝试将存储库 Autowiring 到服务中时,我不断收到 NoSuchBeanDefinitionException 异常。这很
我在 Spring mvc 中遇到错误: (org.springframework.beans.factory.BeanCreationException:创建名称为“webController”的b
我正在使用 spring mvc 开发 Web 应用程序。我想将 spring bean 注入(inject)到我的 Servlet Filter 中。 我引用了这个教程http://www.dead
我们有一个(非 Web 应用程序)Spring 应用程序,在我们的 CruiseControl 持续集成 Linux 盒子上运行测试时会抛出 NoSuchBeanDefinitionException
我想在 BookRestController 中测试我的休息端点。我使用 @WebMvcTest 编写了一个测试。 @RunWith(SpringRunner.class) @WebMvcTest(B
我正在尝试按照官方教程开发我的第一个 Spring MVC 应用程序。我从模板创建了 MVC 项目,然后添加了以下 Spring Security 配置。 pom.xml: ... ...
我正在尝试使用 @RestClientTest 来测试休息客户端类。 据说: It will apply only configuration relevant to rest client test
我想使用ElasticSearch和Spring Data。我添加了此依赖项: org.springframework.boot spring-boot-starter-data-e
当我运行"grails dbm-update --dataSource=production"时,出现以下异常: org.springframework.beans.factory.NoSuchBea
我有一个 Java 桌面应用程序,它通过 Hibernate 连接到 MySql 数据库。 我有以下配置文件: pom.xml,我在其中放置了一些内容和数据库配置文件 [app_name]_conte
我有一个使用 Quartz 调度程序的 Spring Boot (2.1.3) 项目。它是通过启动器包含的: dependencies { ... implementation('or
我正在从事 Spring Hibernate 项目。如果我没有将 bean 名称与 @Repository 或 @Component 一起提及,我会收到错误“NoSuchBeanDefinitionE
我的多模块项目结构如下: project-example (parent) -- project-example-domain: contains DAOs and Services -- proje
我有一个 Spring Boot 应用程序。当我调用 context.getBean(MyController.class) 时,它工作正常。当我调用 context.getBean("MyContr
我是一名优秀的程序员,十分优秀!