2013-08-19 3 views
0

Я разрабатываю API REST в пакете Osgi. Я использую Джерси для развертывания сервисов в контейнере причала с серватом javax для каждого класса с услугами REST.Inject Object на развернутой службе REST

Каждый класс имеет атрибут, как этот

Private DBInterface dbInterface; 

С сеттеров и добытчиками, и мне нужно, чтобы ввести объект из другого пучка, как только служба развертывания (во время выполнения). Так кто-нибудь знает способ сделать это?

Заранее спасибо.

PD: Я хотел бы сделать это без объявления услуги, как одноточечные поэтому каждый запрос REST ответа от другого экземпляра службы (фактический) без гражданства REST

Обновления: web.xml кода я использую для развернуть сервис:

<servlet> 
    <servlet-name>jersey-serlvet</servlet-name> 
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name> 
     <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.classnames</param-name> 
     <param-value>com.mypackage.MyServiceClass</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
     <param-value>true</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>jersey-serlvet</servlet-name> 
    <url-pattern>/rest/*</url-pattern> 
</servlet-mapping> 
+0

Какова конкретная причина, по которой вы не хотите объявлять услугу как singleton? Я думаю, вы можете зарегистрировать объекты в Джерси, чтобы они были предоставлены в качестве службы REST. У вас нет возможности определить фабрику или что-то, что используется для создания экземпляра объекта для каждого запроса. Другой вопрос: как создается экземпляр объекта в другом пакете? Какую технологию или механизм вы используете для создания экземпляра? Вы делаете это в Активаторе или со специальной технологией? Какое событие вызывает другой экземпляр для создания экземпляра этого объекта? –

+0

Является активатором да. Я создаю экземпляр другого объекта, когда пучок, содержащий его, запускается, в активаторе этот объект «настроен», а затем мне нужно ввести его в службу REST. Я подумал, что есть возможность сказать этой службе, чтобы взять этот объект или использовать Джерси, причал или другой пакет или библиотеку, чтобы вводить объект каждый раз, когда создается экземпляр службы. – Koalk

+0

Почему вы хотите создать экземпляр службы несколько раз? Почему это не хорошо, если вы устанавливаете его и создаете экземпляр части, которая отличается для каждого запроса в качестве локальной переменной внутри вашей функции? Как вы регистрируете свое обслуживание в Джерси? Вы настраиваете его в webapp web.xml или используете HTTP-сервис для его программного программирования? У меня такое чувство, что решение было бы довольно простым для вас, но было бы неплохо узнать немного раньше ответа. –

ответ

0

Первое, что нужно сказать, что вы должны зарегистрировать этот объект в другом расслоении активатором в качестве службы OSGi. В этом случае вы сможете получить доступ к нему почти повсеместно.

Другой вопрос: как получить к нему доступ с другой стороны? Есть много возможностей, некоторые из них лучше, некоторые из них хуже.

простой, но на самом деле не красивое решение:

Bundle bundle = FrameworkUtil.getBundle(this.getClass()); 
// Getting the service and using it based on the bundle 

Проблема с этим решением, что для каждого запроса вы должны получить услугу OSGi из реестра OSGi услуг, основанный на фильтрах и уничтожать в зародыше это после того, как вызов функции - лишние накладные расходы.

Решение основано на ServiceTracker:

Если вы используете трекер службы вы столкнулись с проблемой, которую вы должны открыть и закрыть его где-нибудь. Открытие в конструкторе может быть решением, однако вы не найдете места в своем классе отдыха, где вы можете его закрыть. Решением может быть то, что вы создаете прослушиватель сервлета, вы открываете и закрываете там трекер и отправляете трекер службы в карту атрибутов контекста сервлета. В вашей функции REST вы можете получить доступ к контексту сервлета и получить трекер службы в каждом вызове, чем вы можете вызвать tracker.getService(). Эта функция вернет вам нужный объект или null, если он еще не зарегистрирован.

Решение, которое не было необходимости ставить OSGi код, относящийся к REST класса:

Это вероятность того, что вы не хотите использовать ServiceTracker в коде REST, как вы не хотите зависеть от OSGi есть. В этом случае вы можете использовать очень простую библиотеку, которую я реализовал :). Он доступен по адресу https://github.com/everit-org/osgi-servicereference.

Методика такая же. Вы пишете Listener, который: - Создает ServiceReference - Вы вызываете getProxtInstance of serviceReference в ServletContext . Вы получаете прокси-объект на основе интерфейса, который вы предоставили в своей функции REST, и вызываете методы на нем.

ServiceReference был реализован как часть реализации Blueprint.Поэтому он работает так же, как тег работает в XML-файле проекта. Вы можете создать ссылку на службу и открыть ее (после того, как будут открыты службы OSGi). Вы можете получить объект, который реализует необходимые интерфейсы (предоставленные вами) с помощью метода getProxyInstance.

Когда вызов функции производится на объекте на основе вашего интерфейса:

  • Если служба OSGi доступен вызов функции будет делегирована к этой службе
  • Если нет службы OSGi не доступна функция вызов будет удерживаться до таймаута (простой поток .wait). Если есть служба OSGi до таймаута, вызов функции будет делегирован. Если нет, будет выведено исключение ServiceUnavailableException. Вы можете переопределить поведение тайм-аута, установив другой обработчик тайм-аута для объекта ServiceReference.

Вызов нормальной функции выглядит так:

Вызывающий -> OSGiService.function

Вызов функции с помощью объекта ServiceReference прокси выглядит следующим образом:

вызывающему -> ServiceReference.proxyObject - > OSGiService.function (если доступна OSGiService)

Теперь решение на практике:

Вы должны написать слушателя для веб-приложения:

private Reference reference; 

@Override 
public void contextInitialized(final ServletContextEvent sce) { 
    ServletContext servletContext = sce.getServletContext(); 
    BundleContext bundleContext = (BundleContext) servletContext.getAttribute("osgi-bundlecontext"); 

    try { 
     Filter filter = bundleContext.createFilter("(objectClass=" + MyInterface.class.getName() + ")"); 

     // MyInterface is the interface the OSGi service implements (there can be multiple) and the timeout until function calls will wait is 5s. 
     reference = new Reference(bundleContext, new Class<?>[] { MyInterface.class }, filter, 5000); 

     // Opening the reference is necessary to track services 
     reference.open(); 

     // Taking the proxy object into the servlet context attributes 
     servletContext.setAttribute("myService", reference.getProxyInstance()); 
    } catch (InvalidSyntaxException e) { 
     LOGGER.error(e.getMessage(), e); 
    } 
} 

@Override 
public void contextDestroyed(final ServletContextEvent sce) { 
    if (reference != null) { 
     reference.close(); 
     sce.getServletContext().removeAttribute("myService"); 
    } 
} 

После того, как этот приемник вы можете получить прокси-объект, как следующее везде в ваших кодов (где вы можете получить доступ к контексту сервлета):

MyInterface myService = servletContext.getAttribute("myService"); 
myService.foo(); 
+0

Мы заинтересованы в последнем предложенном вами решении, однако нам сложно понять, как работает эта библиотека. Созданный экземпляр справки получает HTTP-запросы для сервисов, а затем ждет, пока экземпляр службы не будет создан или что-то в этом роде? – Koalk

+0

обновил ответ, чтобы получить дополнительную информацию.Если что-то неясно, сообщите мне. Я думаю, что связать этот вопрос stackoverflow в качестве примера из файла readme страницы ServiceReference. Для получения дополнительной информации, пожалуйста, проверьте README и класс javadoc of Reference. –

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