0
votes

I've an EJB as follows:

public class Bar() {

     private String s;

     public Bar() {
         this.s = "bar";
     }

     @Inject public Bar(String s) {
         this.s = s;
     }

}
  1. How can I inject that bean by using the arg-constructor into another Foo class?

  2. Then, I define the Foo class as EJB, with the aim to perform the DI for it into another class (for instance, a WebServlet). How can I inject a Foo class instance by passing a String to properly set up Bar arg-constructor as inner-dependency?

  3. Is there a better way to define Bar in order to achieve points above?

2

2 Answers

3
votes

The annotated constructor injection tells CDI that whenever someone requests an instance of Bar to be injected, it should use the constructor marked with @Inject.

The CDI container then tries to get instances for all required constructor parameters and fails, because it can not deal with "String". It just doesn't know which String you mean.

You have to help the container resolving the dependency by using a Producer and a Qualifier to tell him what String you want. I just give you the simplest possible solution here:

public class Bar {

 @Inject 
 public Bar(@Named("myString") String s) {
     this.s = s;
 }
}

And then another class (doesn't have to be an different class, but its much more readable):

public class MyStringProducer {
  @Produces
  @Named("myString")
  public String getMyString() {
    return ...; // whatever you want ... read JSON, parse properties, randomize ...
  }
}
0
votes

@Inject only works when you are injecting "managed" objects. String is not a managed object, thus this won;t work.

However, the following example should work (I have used spring here. Use the DI initializaton code according to the library you are using):

@Named
public class Foo {

    @Inject
    Bar bar;

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext("com.pkg1");
        Foo foo = (Foo)ctx.getBean("foo");

        System.out.println(foo.bar.getString());

    }


}

@Named
public class Bar {
    private String s;
    public Bar() {
        this.s = "bar";
    }
   @Inject 
   public Bar(Bar1 bar1) {
        this.s = bar1.getS();
    }
    public String getString() {
        return s;
    }
}

@Named
class Bar1 {
    private String s="bar1";
    public String getS() {
        return s;
    }
}