Теперь JSR-299 (по крайней мере, эталонная реализация Weld) может работать на J2SE, но невозможно использовать bean-компоненты, аннотированные как @SessionScoped или @ RequestScoped … на самом деле это не удивительно, потому что нет HttpSession или HttpServletRequest для зацепить С другой стороны, по крайней мере, в инфраструктуре Naked Objects в контексте J2SE у нас есть возможность отобразить эти концепции на собственный внутренний жизненный цикл … например, для клиентского приложения пользователь всегда считается запущенным в одном долгом сеансе.
Как же тогда настроить контексты для этих областей и сделать их автоматически активными при работе в J2SE?
Сначала давайте посмотрим на код, который мы хотим запустить:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
package org.nakedobjects.experiments.cdi;import java.util.List;import javax.enterprise.context.RequestScoped;import javax.enterprise.event.Observes;import org.jboss.weld.environment.se.bindings.Parameters;import org.jboss.weld.environment.se.events.ContainerInitialized;@RequestScopedpublic class HelloWorld { public static void main(String[] args) { // bootstrap org.jboss.weld.environment.se.StartMain.main(new String[]{"JSR","299"}); } public void printHello(@Observes ContainerInitialized event, @Parameters List<String> args) { System.out.println("Hello " + args); System.out.flush(); }} |
Поскольку это бин CDI, нам нужен пустой META-INF / beans.xml.
Приведенный выше класс выведет «Hello [JSR, 299]», если он будет аннотирован как @ApplicationScoped , но не будет аннотирован как @RequestScoped . Поэтому нам нужно написать расширение. Это немного глупо, но работает:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package org.jboss.weld.manager; // required for visibility to BeanManagerImpl#getContexts()import java.lang.annotation.Annotation;import javax.enterprise.context.RequestScoped;import javax.enterprise.context.SessionScoped;import javax.enterprise.event.Observes;import javax.enterprise.inject.spi.AfterDeploymentValidation;import javax.enterprise.inject.spi.BeanManager;import javax.enterprise.inject.spi.Extension;import org.jboss.weld.context.AbstractThreadLocalMapContext;import org.jboss.weld.context.beanstore.HashMapBeanStore;public class WeldServletScopesSupportForSe implements Extension { public void afterDeployment(@Observes AfterDeploymentValidation event, BeanManager beanManager) { setContextActive(beanManager, SessionScoped.class); setContextActive(beanManager, RequestScoped.class); } private void setContextActive(BeanManager beanManager, Class<? extends Annotation> cls) { BeanManagerImpl beanManagerImpl = (BeanManagerImpl) beanManager; AbstractThreadLocalMapContext context = (AbstractThreadLocalMapContext) beanManagerImpl .getContexts().get(cls).get(0); context.setBeanStore(new HashMapBeanStore()); context.setActive(true); }} |
Как и все расширения Weld, это необходимо зарегистрировать в META-INF / services , в данном случае в файле с именем javax.enterprise.inject.spi.Extension, содержащим полное имя класса.
Теперь, когда мы запустим приложение, будут настроены области сеанса и запроса, и сработает наш компонент HelloWorld.
Для разработчиков, пишущих приложения в Naked Objects, они должны будут включить зависимость от дополнительного модуля при развертывании клиента ( -t клиент или сервер на не-веб- сервере (скажем, -t сервер с удаленным взаимодействием на уровне сокетов). В последнем случае нам нужно будет включить некоторые смарты, чтобы выяснить, работаем ли мы в веб-приложении или нет, и настроить контексты только в том случае, если мы определим, что это не так (например, не удается найти классы javax.servlet в CLASSPATH.
Если вы хотите опробовать код, вы можете проверить его, используя
|
1
|
svn co https://nakedobjects.svn.sourceforge.net/svnroot/nakedobjects/framework/trunk/experiments . |
Ссылка: Моделирование объема сеанса и запроса CDI в приложении J2SE от нашего партнера JCG Дэна Хейвуда в блоге Дэна Хейвуда .
Статьи по Теме :