J'utilise Spring depuis quelques mois pour l'instant, et je pensais que l'injection de dépendance avec le @Autowired
l'annotation nécessitait également un setter pour le champ à injecter.
Donc, je l'utilise comme ceci:
@Controller
public class MyController {
@Autowired
MyService injectedService;
public void setMyService(MyService injectedService) {
this.injectedService = injectedService;
}
...
}
Mais j'ai essayé cela aujourd'hui:
@Controller
public class MyController {
@Autowired
MyService injectedService;
...
}
Et oh surprise, pas d'erreurs de compilation, pas d'erreurs au démarrage, l'application fonctionne parfaitement ...
Donc ma question est, est le setter requis pour l'injection de dépendances avec le @Autowired
annotation?
J'utilise Spring 3.1.1.
Vous n'avez pas besoin d'un setter avec @Autowired, la valeur est définie par réflexion.
Consultez cet article pour une explication complète Comment fonctionne Spring @Autowired
Non, si Java permet à Spring de modifier les droits d'accès pour le champ protégé du package, un setter n'est pas requis.
package com.techighost;
public class Test {
private Test2 test2;
public Test() {
System.out.println("Test constructor called");
}
public Test2 getTest2() {
return test2;
}
}
package com.techighost;
public class Test2 {
private int i;
public Test2() {
i=5;
System.out.println("test2 constructor called");
}
public int getI() {
return i;
}
}
package com.techighost;
import Java.lang.reflect.Field;
public class TestReflection {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> class1 = Class.forName("com.techighost.Test");
Object object = class1.newInstance();
Field[] field = class1.getDeclaredFields();
field[0].setAccessible(true);
System.out.println(field[0].getType());
field[0].set(object,Class.forName(field[0].getType().getName()).newInstance() );
Test2 test2 = ((Test)object).getTest2();
System.out.println("i="+test2.getI());
}
}
C'est ainsi que cela se fait en utilisant la réflexion.