CDI Injection through multiple levels?

2019-08-20 05:51发布

I am using CDI to initialize a DataSource (See my previous question: DataSource initialization error within liberty profile server)

public abstract class DAOBase {
    @Resource(name="jdbc/Oracle", lookup = "jdbc/Oracle")
    private DataSource ds;

This works well when the DAO class is initialized directly from the REST class:

@Path("/audit")
public class AuditREST extends RESTBase implements AuditRESTInterface {
    @Inject
    private AuditDAO auditDAO = new AuditDAO();

And when the REST class calls an intermediate class which calls the DAO I can do it by:

public class JobConfigurationREST extends RESTBase implements JobConfigurationRESTInterface {
    @Inject
    private JobRunner jr = new JobRunner();

public class JobRunner implements Runnable{
    @Inject
    private JobConfigurationDAO jcDAO = new JobConfigurationDAO();

However JobRunner also contains a method which creates some instances of a class (SampleModel) on the fly. SampleModel then contains a dao which I need to inject.

public class SampleModel extends Step implements Model {
    @Inject
    private ModelDAO modelDAO = new ModelDAO();

I can see no way of adding the link between JobRunner and SampleModel. How do I do this?

Alternatively, is this even necessary? I feel that having to specify all the links between the REST class and the DAO class is overly complicated, and I should be able to declare SampleModel somewhere (possibly beans.xml?), and the container should take care of everything for me.

EDIT:

I was simplifying the problem here. SampleModel is created via a Job class which is created via a method in a JobBuilder class (which I also can't seem to inject).

JobBuilder jb = new JobBuilder();
Job j = jb.buildJob(jc, jobContext);

SampleModel is also created via reflection deep within the buildJob method.

    public Job buildJob(JobConfiguration inJobConfiguration, JobContext inJobContext) {
stepList.add(ModelFactory.getInstance().getModel(sc.getImplementationName()));
    }

And within the Factory:

ret = (Model) Class.forName(tmpImplDetail.getClassName()).newInstance();

1条回答
Fickle 薄情
2楼-- · 2019-08-20 06:23

Your problem appears to be that you want to move your @Inject into a class that is not a component the container performs injection on.

This is masked by the way you're assigning a new'ed up object to your injection point.

  • In components that actually do support injection, the injection process will happen after the assignment and make it harmless.
  • In objects that the container does not inject for you, you get an object allocated by new that will not have any of its own injection points satisfied.

If you were not doing the weird assignment thing, you'd be asking more of an FAQ of "why is my @Inject field NULL?"

查看更多
登录 后发表回答