Теперь 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; @RequestScoped public 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 Дэна Хейвуда в блоге Дэна Хейвуда .
Статьи по Теме :