Spring-boot,无法自动装配类。未找到默认构造函数引发异常
Posted
技术标签:
【中文标题】Spring-boot,无法自动装配类。未找到默认构造函数引发异常【英文标题】:Spring-boot, unable to autowire a class.No default constructor found Exception is raised 【发布时间】:2013-12-24 22:41:46 【问题描述】:我是弹簧靴的新手。在我将一个类移动到不同的包(另一个包含“应用程序”)后,无法实例化 bean 类:未找到默认构造函数引发异常。
之前(可行的代码)
package com.server;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Controller;
@Configuration
@ComponentScan(basePackages = "com.server" )
@EnableAutoConfiguration
@Profile( "default" )
@Controller
public class Application
private static Log logger = LogFactory.getLog(Application.class);
public static void main(String[] args)
logger.info("Starting Application...");
SpringApplication.run(Application.class, args);
来自http://bitwiseor.com/2013/09/20/creating-test-services-with-spring-boot/的一段代码
package com.server;
import java.util.Collections;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Configuration
@Controller
@Profile( "default" )
class Franchise
private JdbcTemplate jdbcTemplate;
@Autowired
public Franchise(DataSource dataSource)
this.jdbcTemplate = new JdbcTemplate(dataSource);
@ResponseBody
@RequestMapping("/api/franchise/id")
String franchiseId(@PathVariable Long id)
try
return jdbcTemplate.queryForMap("SELECT id, title FROM franchises WHERE id=?", id).toString();
catch(EmptyResultDataAccessException ex)
return Collections.EMPTY_MAP.toString();
@ResponseBody
@RequestMapping("/api/franchise")
String franchises()
try
return jdbcTemplate.queryForList("SELECT id, title FROM franchises").toString();
catch(EmptyResultDataAccessException ex)
return Collections.EMPTY_MAP.toString();
当“Application”类和“Franchise”类位于同一个包中时,我可以启动服务器。但是,当我将类“特许经营”移动到另一个包中时,如下所示,我遇到了这个异常:无法实例化 bean 类:未找到默认构造函数引发异常。
package com.server.api;
import java.util.Collections;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Configuration
@Controller
@Profile( "default" )
class Franchise
private JdbcTemplate jdbcTemplate;
@Autowired
public Franchise(DataSource dataSource)
this.jdbcTemplate = new JdbcTemplate(dataSource);
@ResponseBody
@RequestMapping("/api/franchise/id")
String franchiseId(@PathVariable Long id)
try
return jdbcTemplate.queryForMap("SELECT id, title FROM franchises WHERE id=?", id).toString();
catch(EmptyResultDataAccessException ex)
return Collections.EMPTY_MAP.toString();
@ResponseBody
@RequestMapping("/api/franchise")
String franchises()
try
return jdbcTemplate.queryForList("SELECT id, title FROM franchises").toString();
catch(EmptyResultDataAccessException ex)
return Collections.EMPTY_MAP.toString();
如果我想将这个类移到不同的包中,我该如何解决这个问题?
谢谢!
编辑:我找到了解决方案 当我删除以下标签时,我可以将类放入单独的包中。 @配置 @Profile( "默认" )
但我不知道为什么......
【问题讨论】:
@Configuration
需要一个代理,准确地说是一个 cglib 代理,这反过来又需要一个类有一个默认的构造函数。你的@Controller
不应该是@Configuration
(恕我直言,这违反了单一责任规则)。你的 Application
类也是如此,它不是一个控制器,所以为什么它有一个 @Controller
注释。另请注意,@Profile("default")
是多余的,因为这是默认设置。
@M.Deinum 感谢您的解释!
【参考方案1】:
在我看来,您的 Franchise 类是包私有的(java 类的默认可见性)。这将解释一切(不需要涉及 Spring 或编译器以外的任何东西)。要修复它,只需将您的类声明为“public”。
Marten 也是正确的,@Configuration 可能不希望您对特许经营权意味着什么(但在这种情况下它是无害的)。
【讨论】:
非常感谢您的解释!~以上是关于Spring-boot,无法自动装配类。未找到默认构造函数引发异常的主要内容,如果未能解决你的问题,请参考以下文章
由于未绑定的 RestTemplate,Spring-Boot RestClientTest 无法正确自动配置 MockRestServiceServer
IntelliJ IDEA 2017版 spring-boot2.0.2 自动配置Condition
spring boot自动装配原理@EnableAutoConfiguration
未找到依赖项:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:
使用 @DataJpaTest 的 Spring 测试无法使用 @Repository 自动装配类(但使用接口存储库可以工作!)