2014-11-20 7 views
0

Я использую CDI инициализировать DataSource (см мой предыдущий вопрос: DataSource initialization error within liberty profile server)CDI Инъекция через несколько уровней?

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

Это хорошо работает, когда класс DAO инициализируется непосредственно из класса REST:

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

и когда REST класса вызывает промежуточный класс, который вызывает DAO я могу сделать это с помощью:

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

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

Однако JobRunner также продолжение ains метод, который на лету создает некоторые экземпляры класса (SampleModel). SampleModel затем содержит dao, который мне нужно ввести.

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

Я не вижу возможности добавления ссылки между JobRunner и SampleModel. Как мне это сделать?

В качестве альтернативы, это даже необходимо? Я чувствую, что необходимость указывать все ссылки между классом REST и классом DAO слишком сложна, и я должен иметь возможность объявлять SampleModel где-нибудь (возможно beans.xml?), И контейнер должен заботиться обо всем для меня.

EDIT:

Я упрощая проблему здесь. SampleModel создается с помощью класса Job, который создается с помощью метода в классе JobBuilder (который я также не могу представить).

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

SampleModel также создается путем глубокого отражения в методе buildJob.

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

И в заводе:.

RET = (модель) Class.forName (tmpImplDetail.getClassName()) newInstance();

+1

James, когда вы делаете '@ Inject', не создавайте с помощью' new'. Просто напишите '@Inject private JobRunner jr;' Пожалуйста, также покажите, как вы используете SampleModel. – Gas

+0

Это только для JobRunnner? Is @Inject private AuditDAO auditDAO = новый AuditDAO(); Не так ли? Я уточню вопрос с деталями для SampleModel –

+2

Это вообще.Потому что вся идея состоит в том, что контейнер ** инъецирует ** экземпляр, а не вы создаете его вручную (через 'new'). – Gas

ответ

1

Ваша проблема заключается в том, что вы хотите переместить свой @Inject в класс, который не является компонентом, в который выполняется инжекция.

Это замаскировано тем, как вы назначаете новый объект для вашей точки впрыска.

  • В компонентах, которые на самом деле поддерживают инъекции, процесс инъекции будет после назначения и сделать его безвредным.
  • В объектах, которые контейнер не вводит для вас, вы получаете объект, выделенный новым, который не будет иметь ни одну из своих собственных точек впрыска.

Если вы не выполняете странное задание, вы должны задать более часто задаваемые вопросы «почему мое поле @Inject NULL?»

+0

ok. Итак, как мне обойти это? Доступные параметры, которые я вижу, следующие: (a) Получите контейнер, чтобы вставить ресурс на уровне REST (что немного нехорошо, но будет работать) (b) как-то рассказывать контейнеру о моем классе, чтобы он мог выполнять инъекцию на нем. (если это возможно?) –

+0

Я столкнулся с проблемой, используя поиск JNDI для случая, когда я не могу впрыснуть. Не совсем так быстро, но, по крайней мере, это работает. –

Смежные вопросы