views:

415

answers:

1

I'm working on my first java struts2 webapp and want to be able to inject bean parameters into any arbitrary class that is called. But I find that I can only do this with struts action classes...

Let's say I have this bean in my applicationContext.xml file:

<bean id="BeanTest" class="BeanTest">
    <property name="test" value="someval" />
</bean>

If I have a struts action class setup called BeanTest (like so), and I add a setter (public void setTest()), then the test parameter will be set and I can access it.

import com.opensymphony.xwork2.ActionSupport;

public class BeanTest extends ActionSupport{
    private String test;

    public String execute(){
        String str = getTest(); // returns "someval"
        return "success";
    }

    public void setTest(String test){
        this.test = test;
    }

    public String getTest(){
        return test;
    }
}

However, let's say I change the bean to BeanTest2 like so:

<bean id="BeanTest2" class="BeanTest2">
    <property name="test" value="someval" />
</bean>

And I have a standalone class like so:

public class BeanTest2{
    private test;

    public void setTest(String test){
        this.test = test;
    }

    public String getTest(){
        return test;
    }
}

If I create an instance of BeanTest2 in BeanTest, and call getTest, it always returns null.

import com.opensymphony.xwork2.ActionSupport;

public class BeanTest extends ActionSupport{
    public String execute(){

        BeanTest2 bt = new BeanTest2();
        String str = bt.getTest(); //returns null, but I want "someval"

        return "success";
    }
}

What I want to do is set up a bean in applicationContext so that I can point it to an arbitrary class and that class will always get whatever bean parameters I set (assuming I've created setters for them). Unfortunately, what happens is that only struts action classes are able to get these bean properties. Everything is not getting set.

Is this question clear? I feel like I'm missing something obvious about the way beans work.

+2  A: 

I think Spring will normally do dependency injection only for those classes that are created by Spring, not for the ones that you create yourself with new operator.

BeanTest is created by Spring so it will get its dependencies injected, but BeanTest2 is not created by Spring, thus Spring knows nothing about BeanTest2 instances.

You can add BeanTest2 as a field in BeanTest

public class BeanTest {
   private BeanTest2 beanTest2;
   public void setBeanTest2(BeanTest2 b) { this.beanTest2 = b; }
   public BeanTest2 getBeanTest2() { return this.beanTest2; };
}

Then you can inject beanTest2 to beanTest instance.

<bean id="beanTest2" class="BeanTest2">
    <property name="test" value="someval" />
</bean>

<bean id="beanTest" class="BeanTest">
    <property name="beanTest2" ref="beanTest2" />
</bean>

This way beanTest2 should be injected into BeanTest instance.

Juha Syrjälä
Is the only way to do this, then, to set the bean to BeanTest and pass the resulting parameters to the BeanTest2 constructor? Like BeanTest2(test); ?
Adam Plumb
@Adam, you could do that, or you could inject BeanTest2 directly to BeanTest (see edited answer) or you could obtain reference to ApplicationContext instance and fetch beans directly from that.
Juha Syrjälä
@Juha, wouldn't <property name="beanTest2" value="beanTest2" /> just pass the string "beanTest2" to BeanTest?
Adam Plumb
Yes, you are right, you need to use ref instead of value. Fixed answer.
Juha Syrjälä
Thanks! That works! I just want to clarify for others that you should not instantiate beatTest2 in BeanTest (i.e. beanTest2 = new BeanTest2();). This will cause the spring-created beanTest2 object to be overwritten.
Adam Plumb