2010-11-06 13 views
2

J'ai un contrôleur de ressort qui utilise des annotations. J'ai donné à ce contrôleur un constructeur qui prend deux arguments. Je veux les deux façons d'initialiser le contrôleur: l'injection du constructeur et l'injection du setter.Un contrôleur annoté par ressort nécessite-t-il nécessairement un constructeur par défaut?

@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; 
} 
} 

Lorsque je décommente le constructeur par défaut, le contrôleur est initialisé correctement. Cependant, si je ne le fais pas, j'obtiens une exception BeanInstantiationException, aucun constructeur par défaut trouvé; L'exception imbriquée est java.lang.NoSuchMethodException. Donc, ma configuration pour le constructeur annoté est-elle incorrecte ou est-ce qu'un contrôleur complètement annoté au printemps a toujours besoin d'un constructeur par défaut?

Répondre

4

Si vous souhaitez configurer l'injection de constructeur via des annotations, vous devez placer l'annotation correspondante sur le constructeur. Je ne sais pas comment il peut être fait avec @Resource, mais @Autowired et @Inject soutien qu'elle:

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

ou

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

Merci, la première possibilité d'utiliser @Autowired a travaillé. Je n'ai pas essayé @Inject, parce que cela nécessite de mettre un autre pot dans l'application. Je pense que je vais regarder l'injection de setter avec @Resource plus tard. –

0

Je pense que les haricots contrôleur ont besoin d'un constructeur par défaut car ils sont initialisés par le cadre mais il n'y a aucun moyen de dire le cadre chaud pour fournir la dépendance.

À la réflexion, pourquoi ne pas autowire votre service de questions et Spring s'en occupera. Le code suivant devrait être bon

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

     //Not providing any constructor would also be fine 
     public ViewQuestionController(){} 

questionService sera initialisé correctement au printemps

+1

J'essaie d'éviter les autowiring simples, je veux que le nom de la dépendance soit mentionné quand je l'injecte. J'ai entendu dire que l'autowiring simple n'est pas recommandé quand un projet devient plus grand en taille. –

+0

J'ai travaillé avec de grands projets décents avec un câblage automatique simple et ça marche bien. En fait, la même philosophie est promue par les normes JavaEE avec l'annotation @Resource et l'adoption de la convention sur la configuration. C'était vrai en XML pur que l'auto-apprentissage était difficile à gérer en termes de compréhension des projets, mais avec des annotations et avec la configuration au niveau de la classe, l'autowiring est un meilleur choix. – lalit