简体   繁体   中英

How to invoke Spring setter method before any other class constructor get invoke?

I have an action class and that class will have a BOC object that will fill with Spring Dependency Injection. Below shows the sample code:

public class ActionCls {
  private BOC theBoc = null;

  /*** theBoc getter / setter ***/
}

If I want to call a member function, say thefunc , that belong to BOC inside the ActionCls constructor, like this:

public class ActionCls {
   private BOC theBoc = null;

   ActionCls() {
      theBoc.thefunc();
   }
}

a runtime error will be thrown saying that theBoc is null. I did try to use init-method in spring configuration like this:

<bean id="theBoc" class="com.huahsin68.BOC" init-method="thefunc"></bean>

Anyhow this doesn't help because even though thefunc is get called first, but the theBoc setter is invoke only after ActionCls constructor. Is that a way to call theBoc setter 1st then only ActionCls constructor? So that theBoc is not null and I can invoke thefunc .

You can't expect to call a getter or setter on a class BEFORE its constructor is called. What you want to achieve is not possible. You can better create a parametrized constructor, in which you init theBoc with some argument, using the constuctor-arg param on your ActionCls bean, then call the method:

public class ActionCls {
   private BOC theBoc = null;

   ActionCls(BOC theBoc) {
      this.theBoc = theBoc
      theBoc.thefunc();
   }
}

Then you can define your constructor arg like that:

<bean id="actionCls" class="foo.bar.ActionCls">
        <constructor-arg ref="boc"/>
</bean>

While you can't do what you're asking for (calling a method on property in the constructor, while the property is set via a mutator), you can make use of @PostConstruct to get Spring to invoke a method on your bean once it's been properly assembled.

class ActionCls {
  @Inject
  private BOC boc;

  @PostConstruct
  public void postConstruct() {
    boc.func();
  }
}

See http://docs.oracle.com/javaee/5/api/javax/annotation/PostConstruct.html

In addition to baba's answer, you can use init-method (or @PostConstruct ) to solve this problem, but it should be used on ActionCls rather than on BOC :

public class ActionCls {
    ...
    public void init() {
       theBoc.thefunc();
    }
}

.

<bean ... class="com.huahsin68.ActionCls" init-method="init">...</bean>

I think this approach is more elegant, because init method is guaranteed to be executed when the bean is fully initialized, so that it doesn't depend on type of injection (setter or constructor) you use for your dependencies.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM