Spring java 基于注释的配置不起作用,但基于 xml 的配置可以吗?
Spring java annotation-based config won't work, but xml-based config does?
我一直在关注第 4 版“Spring in Action”一书的第 1 章。
第一章有一个演示依赖注入和 bean 连接的简单示例。
(https://livebook.manning.com/book/spring-in-action-fourth-edition/chapter-1)
我已经将代码复制到 intelliJ 中,但必须制作我自己的项目结构。
我在应用程序上下文方面遇到了一些麻烦。如果我将 xml 文件与 ClassPathXmlApplicationContext 一起使用,它工作正常。但是,当我尝试使用 .java 文件来声明我的 bean 和 AnnotationConfigApplicationContext 时,它不起作用,给我以下错误消息:
org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41a4555e: startup date [Mon Jan 17 20:22:09 GMT 2022]; root of context hierarchy
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springinaction.knights.Knight] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:319)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:987)
at com.springinaction.knights.KnightMain.main(KnightMain.java:12)
2个相关的类如下所示:
src/main/java/com/springinaction/knights/config/KnightBeans.java :
package com.springinaction.knights.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.springinaction.knights.BraveKnight;
import com.springinaction.knights.Knight;
import com.springinaction.knights.Quest;
import com.springinaction.knights.SlayDragonQuest;
@Configuration
public class KnightBeans
{
@Bean
public Knight knight() {
return new BraveKnight(quest());
}
@Bean
public Quest quest() {
return new SlayDragonQuest(System.out);
}
}
src\main\java\com\springinaction\knights\KnightMain.java :
package com.springinaction.knights;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class KnightMain {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
"com.springinaction.knights.config.KnightBeans.class");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
context.close();
}
}
附加信息:
我已经为 Knight 和 Quest 创建了接口,它们由 BraveKnight 和 SlayDragonQuest 类 实现。所有这些以及 KnightMain.java 都位于“骑士”包中。
KnightBeans.java 位于名为 config 的子包中。
我试过将各种类路径放入 new AnnotationConfigApplicationContext() 中,但总是出现相同的错误。
谁能解释这是为什么?
根据 AnnotationConfigApplicationContext
的 javadoc,采用字符串参数的构造函数需要 包的名称 来扫描配置文件。您也可以传递一个或多个 class 对象或工厂。
在您的情况下,Spring 将期望找到一个名为 com.springinaction.knights.config.KnightBeans.class
的包。相反,您可能想传递 class 本身,不带双引号:
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(com.springinaction.knights.config.KnightBeans.class);
你也可以
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext("com.springinaction.knights.config");
扫描 config
包中的所有配置。
当您使用 context.getBean() 获取 bean 时,您需要传递 bean 的方法名称,以便 spring 知道 bean 需要注入什么。
package com.springinaction.knights;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class KnightMain {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
"full class path");
Knight knight = context.getBean("knight",Knight.class);
knight.embarkOnQuest();
context.close();
}
}
并且在 AnnotationConfigApplicationContext
我一直在关注第 4 版“Spring in Action”一书的第 1 章。 第一章有一个演示依赖注入和 bean 连接的简单示例。 (https://livebook.manning.com/book/spring-in-action-fourth-edition/chapter-1)
我已经将代码复制到 intelliJ 中,但必须制作我自己的项目结构。 我在应用程序上下文方面遇到了一些麻烦。如果我将 xml 文件与 ClassPathXmlApplicationContext 一起使用,它工作正常。但是,当我尝试使用 .java 文件来声明我的 bean 和 AnnotationConfigApplicationContext 时,它不起作用,给我以下错误消息:
org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41a4555e: startup date [Mon Jan 17 20:22:09 GMT 2022]; root of context hierarchy
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springinaction.knights.Knight] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:319)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:987)
at com.springinaction.knights.KnightMain.main(KnightMain.java:12)
2个相关的类如下所示:
src/main/java/com/springinaction/knights/config/KnightBeans.java :
package com.springinaction.knights.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.springinaction.knights.BraveKnight;
import com.springinaction.knights.Knight;
import com.springinaction.knights.Quest;
import com.springinaction.knights.SlayDragonQuest;
@Configuration
public class KnightBeans
{
@Bean
public Knight knight() {
return new BraveKnight(quest());
}
@Bean
public Quest quest() {
return new SlayDragonQuest(System.out);
}
}
src\main\java\com\springinaction\knights\KnightMain.java :
package com.springinaction.knights;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class KnightMain {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
"com.springinaction.knights.config.KnightBeans.class");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
context.close();
}
}
附加信息: 我已经为 Knight 和 Quest 创建了接口,它们由 BraveKnight 和 SlayDragonQuest 类 实现。所有这些以及 KnightMain.java 都位于“骑士”包中。 KnightBeans.java 位于名为 config 的子包中。
我试过将各种类路径放入 new AnnotationConfigApplicationContext() 中,但总是出现相同的错误。
谁能解释这是为什么?
根据 AnnotationConfigApplicationContext
的 javadoc,采用字符串参数的构造函数需要 包的名称 来扫描配置文件。您也可以传递一个或多个 class 对象或工厂。
在您的情况下,Spring 将期望找到一个名为 com.springinaction.knights.config.KnightBeans.class
的包。相反,您可能想传递 class 本身,不带双引号:
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(com.springinaction.knights.config.KnightBeans.class);
你也可以
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext("com.springinaction.knights.config");
扫描 config
包中的所有配置。
当您使用 context.getBean() 获取 bean 时,您需要传递 bean 的方法名称,以便 spring 知道 bean 需要注入什么。
package com.springinaction.knights;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class KnightMain {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
"full class path");
Knight knight = context.getBean("knight",Knight.class);
knight.embarkOnQuest();
context.close();
}
}
并且在 AnnotationConfigApplicationContext