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

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

Я использую 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();
   }
}

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

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

Кто-нибудь знает лучший способ решить мою проблему?

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

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

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

1 ответ

Поскольку реализация примера не выполняется в контейнере CDI, инъекция не происходит. Что вы можете сделать, это искать компонент вручную, используя 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 - это зависимость, которую вы ищете.

Другие вопросы по тегам