【问题标题】:Does a Spring annotated controller necessarily need a default constructorSpring带注释的控制器是否一定需要默认构造函数
【发布时间】:2011-05-06 03:48:38
【问题描述】:

我有一个使用注释的弹簧控制器。我给了这个控制器一个带有两个参数的构造函数。我想要两种初始化控制器的方法:构造函数注入和 setter 注入。

@Controller("viewQuestionController")
@RequestMapping("/public/viewQuestions")
public class ViewQuestionController
{
    @Resource(name="questionService")
    private QuestionService questionService;

   /*public ViewQuestionController()
 {
    int i=0;
    i++;
 } 
   */   

public ViewQuestionController(@Qualifier("questionService") QuestionService questionService)
{
    this.questionService = questionService;
}

@Resource(name="questionService")
public void setQuestionService(QuestionService questionService)
{
    this.questionService = questionService;
}
}   

当我取消注释默认构造函数时,控制器会正确启动。但是,如果我不这样做,我会得到一个 BeanInstantiationException,没有找到默认构造函数;嵌套异常是 java.lang.NoSuchMethodException。 那么,我对带注释的构造函数的配置是错误的,还是 Spring 中完全带注释的控制器总是需要默认构造函数?

【问题讨论】:

    标签: spring annotations


    【解决方案1】:

    如果要通过注解配置构造函数注入,需要在构造函数上打上对应的注解。我不确定如何使用@Resource 来完成,但@Autowired@Inject 支持它:

    @Autowired
    public ViewQuestionController(@Qualifier("questionService") QuestionService questionService) 
    

    @Inject
    public ViewQuestionController(@Named("questionService") QuestionService questionService) 
    

    【讨论】:

    • 谢谢,使用@Autowired 的第一个选项有效。我没有尝试@Inject,因为这需要在应用程序中放置另一个 jar。我想我稍后会用@Resource 来看看 setter 注入。
    • 我认为在问题的情况下,用@Controller注释的类,用@Autowired注释构造函数是没有必要的,虽然它没有伤害?如果我是对的,构造函数上的自动装配会从 @Controller 自动发生。
    • @cellepo 你是对的......从 Spring 4.3 开始,当 bean 只有一个构造函数时,Autowired 注释是可选的。 docs.spring.io/spring/docs/4.3.x/spring-framework-reference/…
    【解决方案2】:

    我认为 Controller bean 需要一个默认构造函数,因为它们是由框架初始化的,但是没有办法告诉框架热提供依赖项。

    再三考虑为什么不自动连接您的问题服务,Spring 会处理它。 下面的代码应该不错

     @Controller("viewQuestionController")
     @RequestMapping("/public/viewQuestions")
     public class ViewQuestionController
     {
           @Autowired
           private QuestionService questionService;
    
           //Not providing any constructor would also be fine
           public ViewQuestionController(){}
    

    questionService 会被 Spring 正确初始化

    【讨论】:

    • 我试图避免简单的自动装配,我希望在注入时提及依赖项的名称。我听说当项目变得更大时,不建议使用简单的自动装配。
    • 我用简单的自动接线处理过相当大的项目,它工作得很好。事实上,JavaEE 标准也通过 @Resource 注释和采用约定优于配置来推广相同的理念。在纯 XML 方式中,自动装配过去确实很难在理解项目方面进行管理,但是通过注释和位于类级别的配置,自动装配是更好的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2017-03-02
    相关资源
    最近更新 更多