原文网址:SpringBoot--解决注入实现类导致的启动失败问题_IT利刃出鞘的博客-CSDN博客
简介
说明
本文介绍SpringBoot注入实现类导致的启动失败的解决方案。
问题描述
- 注册bean时,返回值类型是接口,方法里创建了一个实现类。
- 通过@Autowired注入实现类,结果报错了,应用启动失败。
- 通过@Autowired注入接口,启动成功。
- 通过@Autowired注入接口,通过@Autowired注入实现类,启动成功。
问题复现
注入实现类启动失败
package com.knife;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
public class DemoApplication {
@Autowired
private DistributeLock distributeLock;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Configuration
class LockConfig{
@Bean
public Lock lock() {
return new DistributeLock();
}
}
interface Lock{}
class DistributeLock implements Lock{}
报错信息(无法找到com.knife.DistributeLock这个bean)
2022-09-10 16:37:43.419 INFO 142692 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1013 ms
2022-09-10 16:41:28.518 WARN 142692 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'demoApplication': Unsatisfied dependency expressed through field 'distributeLock'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.knife.DistributeLock' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2022-09-10 16:41:28.521 INFO 142692 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2022-09-10 16:41:28.533 INFO 142692 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-09-10 16:41:28.601 ERROR 142692 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field distributeLock in com.knife.DemoApplication required a bean of type 'com.knife.DistributeLock' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.knife.DistributeLock' in your configuration.
2022-09-10 16:41:28.607 WARN 142692 --- [ main] o.s.boot.SpringApplication : Unable to close ApplicationContext
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springApplicationAdminRegistrar' defined in class path resource [org/springframework/boot/autoconfigure/admin/SpringApplicationAdminJmxAutoConfiguration.class]: Unsatisfied dependency expressed through method 'springApplicationAdminRegistrar' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.env.Environment' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:539) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.
注入接口启动成功
package com.knife;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
public class DemoApplication {
@Autowired
private Lock lock;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Configuration
class LockConfig{
@Bean
public Lock lock() {
return new DistributeLock();
}
}
interface Lock{}
class DistributeLock implements Lock{}
结果(启动成功)
注入接口和实现类启动成功
package com.knife;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
public class DemoApplication {
@Autowired
private Lock lock;
@Autowired
private DistributeLock distributeLock;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Configuration
class LockConfig{
@Bean
public Lock lock() {
return new DistributeLock();
}
}
interface Lock{}
class DistributeLock implements Lock{}
原因分析
报错原因概述
Spring是通过类型来匹配bean的,DemoApplication需要的是DistributeLock类型的bean,但找不到(只有Lock类型的bean),于是报错。
源码追踪
解决方案
扫描二维码关注公众号,回复:
14541221 查看本文章