-2

I am trying to learn spring framework static method dependency injection, there are many questions posted already but my problem is different, in that I have taken one class

 package com.model;

    public class Test {

      private static String name;
      //private static Engine  engine;


     public static void setName(String name) {
        Test.name = name;
    }

    public  static void printData(){
      System.out.println("Helllo: "+name);
    }
 }

and want to inject one property call name and checking does it support regular DI by injecting data using spring.xml

spring.xml contains

<bean id="t" class="com.model.Test">
    <property name="name" value="Vishal"/>
</bean>

passing value through property and in main

ApplicationContext ap = new ClassPathXmlApplicationContext("resources/spring.xml");
    Test test = (Test)ap.getBean("t");
    test.printData();

while I am running this code it works fine.

I doesn't come to know how it support instead of throwing some exception as spring doc it has to pass through

 org.springframework.beans.factory.config.MethodInvokingFactoryBean

I am using spring 4, whats wrong with my code??

Vishal Kawade
  • 449
  • 6
  • 20

2 Answers2

0

Dependency Injection is not a method you use to inject values using static method/fields. Consider having two beans defined for the same class:

<bean id="t1" class="com.model.Test">
    <property name="name" value="Vishal"/>
</bean>
<bean id="t2" class="com.model.Test">
    <property name="name" value="Lorem ipsum"/>
</bean>

Your static method modifies a static field which is shared across all instances. Let's say Spring allows you to do so (I'm not sure if this is possible, never tried doing something like that, because this is anti-pattern). Let's also assume that t1 instance get instantiated in the first place. After instantiating t2 you will get:

t1.printData()
// Output: Hello: Lorem ipsum

What is even more problematic, you can at any time something like this:

Test t3 = new Test();
t3.setName("Foo");

You do it outside Spring Dependency Injection container, t3 is simply a local variable and has nothing to do with Spring, however calling t3.setName("Foo) affects beans t1 and t2 - you see the problem?

Conclusion - use Spring DI container to instantiate classes with non-static fields and methods. Spring (by default) creates a single instance of each bean and you can share it across the whole application. It's also important to make those beans stateless - if start changing their state after initialization you may run into troubles very quickly. Try searching for "spring dependency injection best practices" to get some good examples on how to use Spring.

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
0

A static variable is class label variable. So, when the Class loaded it is possibly Spring context does not loaded still that time. However, there is a workaround by making the setter non-static it will work. But I believe this should not be required in your application. Such type of requirement may indicate bad design and you should revisit the design of the application. Here is the workaround by making setter non-static. Workaround:

package com.model;

    public class Test {

      private static String name;
      //private static Engine  engine;


     public void setName(String name) {
        Test.name = name;
    }

    public  static void printData(){
      System.out.println("Helllo: "+name);
    }
 }
Amit Bera
  • 7,075
  • 1
  • 19
  • 42