Как сделать сервис-загрузчик созданным классом-контейнером управляемых объектов

В настоящее время я пишу библиотеку, в которой я хочу, чтобы пользователь моей библиотеки реализовал интерфейс. Из своей библиотеки я вызываю эту реализацию.

Я использую ServiceLoader для создания экземпляра реализации, предоставленной интегратором, и он отлично работает. Интегратор вызывает метод start() в моей библиотеке и в итоге получает что-то взамен. Реализация используется, чтобы дать мне некоторые вещи, которые мне нужны для достижения конечного результата. (Я намеренно не использую CDI или любой другой контейнер DI, потому что я хочу создать библиотеку, которую можно использовать где угодно. В настольном приложении приложение Spring приложение, использующее guice...)

Теперь я столкнулся с проблемой. Я создаю витрину, в которой использую свою собственную библиотеку. Это веб-приложение, в котором я использую jsf и CDI. Когда я создаю реализацию, предоставленную в указанном веб-приложении, из моей библиотеки, я имею дело с управляемым объектом, не являющимся контейнером. Но поскольку эта реализация должна использовать объекты, управляемые контейнером, я немного облажался, так как это никогда не сработает.

Пример: Интерфейс в lib:

public interface Example{
   public abstract String getInfo();
}

Реализация на войне:

public class ExampleImpl implements Example{

   @Inject
   private ManagedBean bean;
   public String getInfo(){
      return bean.getSomethingThatReturnsString();
   }
}

Как вы можете видеть, это огромная проблема в том, как создается моя библиотека, поскольку bean-компонент всегда будет нулевым... Это означает, что никто, использующий DI-контейнер, не может использовать мою библиотеку. Я знаю, что могу получить управляемый компонент, выполнив поиск FacesContext и получив управляемый компонент, но, что более важно, моя библиотека не очень хорошо спроектирована, если подумать.

Итак, чтобы завершить мой вопрос (вопросы): могу ли я каким-либо образом заставить загрузчик служб использовать контейнер DI для создания экземпляра класса?

Кто знает, как лучше решить мою проблему?

Кто-нибудь, кто знает лучший способ получить то, что мне нужно, не заставляя интегратора реализовывать интерфейс, но я могу получить информацию от интегратора?

Я знаю, что это довольно абстрактный вопрос, но я как бы застрял на этом.

заранее спасибо


person KwintenP    schedule 21.08.2013    source источник


Ответы (1)


Поскольку реализация примера не выполняется внутри контейнера CDI, внедрение не происходит. Что вы можете сделать, так это найти bean-компонент вручную с помощью BeanManager. Согласно документам, BeanManager привязан к имени jndi java:comp/BeanManager. Используя следующий код, вы можете получить BeanManager в своем классе реализации и найти зависимости вручную:

InitialContext context = new InitialContext();
BeanManager beanManager = (BeanManager) context.lookup("java:comp/BeanManager");
Set<Bean<?>> beans = beanManager.getBeans(YourBean.class, new AnnotationLiteral<Default>() {});
Bean<YourBean> provider = (Bean<YourBean>) beans.iterator().next();
CreationalContext<YourBean> cc = beanManager.createCreationalContext(provider);
YourBean yourBean = (YourBean) beanManager.getReference(provider, YourBean.class, cc);

где YourBean — это искомая зависимость.

person Adrian Mitev    schedule 23.08.2013