Reputation: 962
I was just trying to test the injection of static variables in the Spring 4.2. As i was following a tutorial, in that Spring 2.0 was used. In that tutorial if it was done as follows:
public class Car {
private static String carName;
public static void setCarName(String carName) {
Car.carName = carName;
}
public static void printCar(){
System.out.println("Car name is: " + carName);
}
}
And my xml file is:
<beans>
<bean id="c" class="beans.Car">
<property name="carName" value="Audi"/>
</bean>
</beans>
And my class to test it is:
public class Client {
public static void main(String[] args) {
ApplicationContext ap= new ClassPathXmlApplicationContext("resources/spring.xml");
Car car= (Car)ap.getBean("c");
car.printCar();
}
}
The above code was throwing error when used with Spring 2.0(as shown in the tutorial I was following). But if I am trying the same code in Spring 4.2, it is not showing any error and the code is working fine. Why is the difference in behavior?? Does Spring make any changes in the newer version for injection of static variables? So my question is can we do the DI of static variables directly as shown above??
Upvotes: 2
Views: 566
Reputation: 5
Spring is not responsible for managing and injection of static entities .That's because spring believes in dependency injection and the whole point of D DI is that object dependancies can be decoupled and can be managed as a service and client relation. The whole point of dependency injection is so that the client depends on the service for its configuration.
Expecting spring to inject static methods/setters/variables is a big misunderstanding.Because there is something fundamentally evil with static variables or methods.
So the question arise that why won't Spring (which is so smart with its service-client resolution techniques) simply allow static methods and variables to be managed by it?
Let's prove this by contradiction:
Let's assume that spring allows DI for static members(specifically variable for this case but can be equally understood for methods to).
So let's have a go at your code but obviously with prototype scope to understand clearly and also because Spring should behave equivocably irrespective of the scope.
public class Car {
private static String carName;
public static void setCarName(String carName) {
Car.carName = carName;
}
public static void printCar(){
System.out.println("Car name is: " + carName);
}
}
And here's the modified xml:
<beans>
<bean id="c" class="beans.Car" scope="prototype">
<property name="carName" value="Audi"/>
</bean>
<bean id="d" class="beans.Car" scope="prototype">
<property name="carName" value="Dodge"/>
</bean>
</beans>
Now you've written a service to get you your car in the morning:
@Service
public class GetCarInTheMorningService{
@Qualifier("c")
@Autowired
private Car myCar;
public Car getMyCar(){
reutrn myCar;
}
}
Now you expect Sping to get you Audi in the morning but you but you got stuck with a dodge and that makes spring look stupid because the whole reason of letting spring handle the DI is to get the precise and required dependencies.
and hence spring uses this pattern(anti-pattern?).
Upvotes: 0
Reputation:
The intention of ExtendedBeanInfo, introduced with SPR-8079 in v3.1.0.M2, was to support dependency injection against non-void returning write methods. However, it also inadvertently introduced support for injection against static setter methods.
SPR-8079 shows that this is supported since 3.1 M2
Car
is a spring managed bean, it's a singleton, so no need to use static methods/field in your example.Upvotes: 5