Le domaine annoté @Autowired
est null
parce que le Printemps ne sais pas à propos de la copie d' MileageFeeCalculator
que vous avez créé avec new
et je ne savais pas à autowire.
Le Printemps de l'Inversion de Contrôle (IoC) contenant les trois principaux composants logiques: un registre (appelé l' ApplicationContext
) des composants (haricots) qui sont disponibles pour être utilisés par l'application, configurer un système qui injecte des objets dépendances par correspondance de toutes les dépendances avec des haricots dans le contexte, et une dépendance solveur qui peut regarder une configuration de nombreux types de haricots et de déterminer comment instancier et de les configurer dans l'ordre nécessaire.
Le conteneur IoC n'est pas de la magie, et il n'a aucun moyen de savoir au sujet des objets Java, à moins que vous en quelque sorte l'en informer. Lorsque vous appelez new
, la JVM instancie une copie de l'objet nouveau et les mains directement à vous, il ne va jamais à travers le processus de configuration. Il y a trois façons que vous pouvez obtenir vos haricots configuré.
J'ai posté tout ce code, à l'aide de Printemps de Démarrage pour lancer, à ce projet GitHub; vous pouvez envisager un projet en cours d'exécution pour chaque approche pour voir tout ce dont vous avez besoin pour le faire fonctionner. La balise avec l' NullPointerException
: nonworking
Injecter des haricots
Le plus préférable option est de laisser le Printemps autowire tous vos haricots; ce qui nécessite le moins de code et est le plus facile à gérer. Pour rendre le travail permettra à l'autowiring comme tu le voulais, aussi autowire l' MileageFeeCalculator
comme ceci:
@Controller
public class MileageFeeController {
@Autowired
private MileageFeeCalculator calc;
@RequestMapping("/mileage/{miles}")
@ResponseBody
public float mileageFee(@PathVariable int miles) {
return calc.mileageCharge(miles);
}
}
Si vous avez besoin de créer une nouvelle instance de l'objet de service pour des demandes différentes, vous pouvez toujours utiliser l'injection en utilisant le Printemps bean étendues.
Balise qui fonctionne par l'injection de la @MileageFeeCalculator
service objet: working-inject-bean
Utiliser @Configurable
Si vous avez vraiment besoin des objets créés à l' new
à autocâblés, vous pouvez utiliser le Printemps @Configurable
d'annotation avec AspectJ au moment de la compilation de tissage à injecter de vos objets. Cette approche insère le code dans votre constructeur de l'objet que les alertes de Printemps qu'il a été créé de sorte que le Ressort peut configurer la nouvelle instance. Cela nécessite un peu de configuration dans votre construction (comme par exemple la compilation avec ajc
) et de tournage sur le Printemps de la configuration de l'exécution des gestionnaires d' (@EnableSpringConfigured
avec le JavaConfig syntaxe). Cette approche est utilisée par le Roo Active système d'Enregistrement pour permettre l' new
instances de votre entités pour obtenir les informations persistance injecté.
@Service
@Configurable
public class MileageFeeCalculator {
@Autowired
private MileageRateService rateService;
public float mileageCharge(final int miles) {
return (miles * rateService.ratePerMile());
}
}
Balise qui fonctionne en utilisant de l' @Configurable
sur le service de l'objet: working-configurable
Manuel de haricot de recherche: non recommandé
Cette approche est adaptée uniquement pour l'interfaçage avec le code existant dans des situations particulières. Il est presque toujours préférable de créer un singleton adaptateur classe que le Printemps peut autowire et le code héritage pouvez l'appeler, mais il est possible de demander directement au Printemps contexte de l'application pour un haricot.
Pour ce faire, vous avez besoin d'une classe à laquelle Printemps peut donner une référence à l' ApplicationContext
objet:
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
}
Puis votre code hérité peut appeler getContext()
et de récupérer les haricots elle a besoin:
@Controller
public class MileageFeeController {
@RequestMapping("/mileage/{miles}")
@ResponseBody
public float mileageFee(@PathVariable int miles) {
MileageFeeCalculator calc = ApplicationContextHolder.getContext().getBean(MileageFeeCalculator.class);
return calc.mileageCharge(miles);
}
}
Balise qui fonctionne manuellement en recherchant l'objet de service au Printemps contexte: working-manual-lookup