Voici mon code:
public class Main {
public static void main(String[] args) {
Main p = new Main();
p.start(args);
}
@Autowired
private MyBean myBean;
private void start(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/config.xml");
System.out.println("my beans method: " + myBean.getStr());
}
}
@Service
public class MyBean {
public String getStr() {
return "string";
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="mypackage"/>
</beans>
Pourquoi ça ne marche pas? Je reçois NullPointerException
. Est-il possible d'utiliser l'auto-câblage dans une application autonome?
Spring fonctionne en application autonome. Vous utilisez la mauvaise façon de créer un haricot de printemps. La bonne façon de le faire comme ça:
@Component
public class Main {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/config.xml");
Main p = context.getBean(Main.class);
p.start(args);
}
@Autowired
private MyBean myBean;
private void start(String[] args) {
System.out.println("my beans method: " + myBean.getStr());
}
}
@Service
public class MyBean {
public String getStr() {
return "string";
}
}
Dans le premier cas (celui de la question), vous créez l'objet par vous-même, plutôt que de l'obtenir à partir du contexte Spring. Donc, Spring n'a pas l'occasion de Autowire
les dépendances (ce qui cause le NullPointerException
).
Dans le second cas (celui de cette réponse), vous obtenez le haricot du contexte Spring, qui est donc géré par Spring et Spring prend en charge autowiring
.
Spring s'éloigne des fichiers XML et utilise beaucoup les annotations. L'exemple suivant est une simple application Spring autonome qui utilise des annotations au lieu de fichiers XML.
package com.zetcode.bean;
import org.springframework.stereotype.Component;
@Component
public class Message {
private String message = "Hello there!";
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
Ceci est un haricot simple. Il est décoré avec le @Component
annotation pour la détection automatique par le conteneur Spring.
package com.zetcode.main;
import com.zetcode.bean.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "com.zetcode")
public class Application {
public static void main(String[] args) {
ApplicationContext context
= new AnnotationConfigApplicationContext(Application.class);
Application p = context.getBean(Application.class);
p.start();
}
@Autowired
private Message message;
private void start() {
System.out.println("Message: " + message.getMessage());
}
}
C'est la classe principale Application
. Le @ComponentScan
annotation recherche des composants. Le @Autowired
annotation injecte le bean dans la variable message
. Le AnnotationConfigApplicationContext
est utilisé pour créer le contexte d'application Spring.
Mon tutoriel Spring autonome montre comment créer une application Spring autonome avec XML et des annotations.
Pour Spring 4, en utilisant Spring Boot, nous pouvons avoir l'exemple suivant sans utiliser l'anti-pattern d'obtention directe du bean depuis ApplicationContext:
package com.yourproject;
@SpringBootApplication
public class TestBed implements CommandLineRunner {
private MyService myService;
@Autowired
public TestBed(MyService myService){
this.myService = myService;
}
public static void main(String... args) {
SpringApplication.run(TestBed.class, args);
}
@Override
public void run(String... strings) throws Exception {
System.out.println("myService: " + MyService );
}
}
@Service
public class MyService{
public String getSomething() {
return "something";
}
}
Assurez-vous que tous vos services injectés sont sous com.yourproject
ou ses sous-packages.