英文:
Spring Boot: NoSuchBeanDefinitionException
问题
我有一个关于Spring Boot应用程序的问题:
spring.bat init --artifactId=dbproto4 --boot-version=2.1.7.RELEASE --dependencies=jdbc,data-rest,web,thymeleaf,devtools,lombok,configuration-processor,security,data-jpa,data-jdbc,postgresql,actuator --description=dbproto4 --groupId=com.test --java-version=11 --name=dbproto4 --package-name=com.test.dbproto4 --version=0.0.1-SNAPSHOT
这是一个异常:
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'testService' available
所有文件都位于应用程序根目录下。
Dbproto4Application:
@SpringBootApplication
public class Dbproto4Application {
public static void main(String[] args) {
SpringApplication.run(Dbproto4Application.class, args);
ApplicationContext javaConfigContext = new AnnotationConfigApplicationContext(SpringConfig.class);
TestService testServiceObj = (TestService) javaConfigContext.getBean("testService");
testServiceObj.addNewUser();
}
}
SpringConfig:
@EnableJdbcRepositories(basePackages = "com.test.dbproto4.infrastructure.storage.jdbcrepos")
@Configuration
public class SpringConfig { }
User:
@Entity
@Table(name = "userstab")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
// ...
}
UserRepository:
public interface UserRepository extends CrudRepository<User, Integer> {
}
application.properties:
server.port = 8082
## default connection pool
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
## PostgreSQL
spring.datasource.url=jdbc:postgresql://localhost:5432/example_db4
spring.datasource.username=someuser
spring.datasource.password=123456
spring.jpa.hibernate.ddl-auto=update
http://localhost:8084/actuator/beans/:
"testService": {
"aliases": [],
"scope": "singleton",
"type": "com.test.dbproto4.TestService",
"resource": "file [E:\\Java\\JavaProjects\\dbproto4\\target\\classes\\com\\test\\dbproto4\\TestService.class]",
"dependencies": [
"userRepository"
]
}
"userRepository": {
"aliases": [],
"scope": "singleton",
"type": "com.test.dbproto4.UserRepository",
"resource": null,
"dependencies": [
"(inner bean)#667aba3e",
"(inner bean)#22b3117e",
"(inner bean)#2607b66f",
"jpaMappingContext"
]
}
Actuator显示了名为"testService"的bean,但Spring看不到它。如何从ApplicationContext中获取"testService" bean?
英文:
I have a problem with Spring Boot application:
spring.bat init --artifactId=dbproto4 --boot-version=2.1.7.RELEASE --dependencies=jdbc,data-rest,web,thymeleaf,devtools,lombok,configuration-processor,security,data-jpa,data-jdbc,postgresql,actuator --description=dbproto4 --groupId=com.test --java-version=11 --name=dbproto4 --package-name=com.test.dbproto4 --version=0.0.1-SNAPSHOT
It is an exception:
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'testService' available
All files are in application root
Dbproto4Application:
@SpringBootApplication
public class Dbproto4Application {
public static void main(String[] args) {
SpringApplication.run(Dbproto4Application.class, args);
ApplicationContext javaConfigContext = new AnnotationConfigApplicationContext(SpringConfig.class);
TestService testServiceObj = (TestService) javaConfigContext.getBean("testService");
testServiceObj.addNewUser();
SpringConfig:
@EnableJdbcRepositories(basePackages = "com.test.dbproto4.infrastructure.storage.jdbcrepos")
@Configuration
public class SpringConfig { }
User:
@Entity
@Table(name = "userstab")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
...
}
UserRepository:
public interface UserRepository extends CrudRepository<User, Integer> {
}
application properties:
server.port = 8082
## default connection pool
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
## PostgreSQL
spring.datasource.url=jdbc:postgresql://localhost:5432/example_db4
spring.datasource.username=someuser
spring.datasource.password=123456
spring.jpa.hibernate.ddl-auto=update
http://localhost:8084/actuator/beans/:
"testService": {
"aliases": [],
"scope": "singleton",
"type": "com.test.dbproto4.TestService",
"resource": "file [E:\\Java\\JavaProjects\\dbproto4\\target\\classes\\com\\test\\dbproto4\\TestService.class]",
"dependencies": [
"userRepository"
]
}
"userRepository": {
"aliases": [],
"scope": "singleton",
"type": "com.test.dbproto4.UserRepository",
"resource": null,
"dependencies": [
"(inner bean)#667aba3e",
"(inner bean)#22b3117e",
"(inner bean)#2607b66f",
"jpaMappingContext"
]
}
Actuator shows the bean named "testService", but Spring doesn't see it.
How can i get bean "testService" from ApplicationContext?
答案1
得分: 0
Solution
对于你的 Dbproto4Application
类,执行以下更改:
ApplicationContext javaConfigContext = SpringApplication.run(Dbproto4Application.class, args);
TestService testServiceObj = (TestService) javaConfigContext.getBean("testService");
Problem
在你的 Spring Boot 应用程序中,你配置了两个不同的 Spring 应用程序上下文。
// 第一个应用程序上下文,也是 Actuator 端点所引用的上下下文
SpringApplication.run(Dbproto4Application.class, args);
// 第二个应用程序上下文,在这里从 SpringConfig 类创建,你想要获取 testService bean
ApplicationContext javaConfigContext = new AnnotationConfigApplicationContext(SpringConfig.class);
TestService testServiceObj = (TestService) javaConfigContext.getBean("testService");
请注意,你创建的第二个应用程序上下文是从 SpringConfig
创建的,它只能访问位于 com.test.dbproto4.infrastructure.storage.jdbcrepos 包中定义的 bean。它无法访问 testService
bean。
英文:
Solution
Perform these changes to your Dbproto4Application class
ApplicationContext javaConfigContext = SpringApplication.run(Dbproto4Application.class, args);
TestService testServiceObj = (TestService) javaConfigContext.getBean("testService");
Problem
Inside your Spring boot application, you have configured 2 different spring application contexts.
// 1st application context and the one which Actuator endpoint is referring to
SpringApplication.run(Dbproto4Application.class, args);
// 2nd application context which is created here from which you want testService bean
ApplicationContext javaConfigContext = new AnnotationConfigApplicationContext(SpringConfig.class);
TestService testServiceObj = (TestService) javaConfigContext.getBean("testService");
Notice that the 2nd application context which you created is built from SpringConfig which only has access to beans which are defined inside com.test.dbproto4.infrastructure.storage.jdbcrepos package. It does not have access to testService bean.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论