SeamFramework.orgCommunity Documentation
Se você está usando JBoss AS 6.0, nenhuma configuração adicional é necessária para usar Weld (ou CDI para este caso). Tudo que você precisa fazer é tornar sua aplicação em um bean archive adicionando META-INF/beans.xml
ao classpath ou WEB-INF/beans.xml
à raiz web!
Adicionalmente, a Servlet do Weld suporta o JBoss EAP 5.1, usando a variante jboss5
da Servlet do Weld.
O Weld também está embutido no GlassFish a partir da V3 e posteriores. Já que o GlassFish V3 é a implementação de referência da Java EE 6, ele deve suportar todas as funcionalidades da CDI. Qual a melhor maneira para que o GlassFish suporte estas funcionalidade do que usar Weld, a implementação de referência da JSR-299? Apenas empacote sua aplicação CDI e implante.
Enquanto a JSR-299 não requer suporte a ambientes servlet, o Weld pode ser utilizado em qualquer contêiner Servlet, como o Tomcat 6.0 ou Jetty 6.1.
Há uma limitação maior no uso de um contêiner servlet. O Weld não suporta a implantação de session beans, injeção usando @EJB
ou @PersistenceContext
, ou a utilização de eventos transacionais em contêineres servlet. Para funcionalidades corporativas como estas, você deveria realmente procurar um servidor de aplicações Java EE.
O Weld pode ser usado como uma biblioteca de aplicação web em um contêiner Servlet. Você deve colocar weld-servlet.jar
dentro do diretório WEB-INF/lib
relativo à raiz web. weld-servlet.jar
é um "uber-jar", significando que ele empacota todas as partes do Weld e CDI necessárias para rodar em um contêiner servlet, para sua conveniência. Alternativamente, você pode usar seus jars componentes. Uma lista de dependências pode ser encontrada no arquivo META-INF/DEPENDENCIES.txt
dentro do artefato weld-servlet.jar
.
Você também precisa especificar explicitamente o servlet listener (usado para iniciar o Weld e controlar a interação com as requisições) no web.xml
:
<listener>
<listener-class
>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener
>
O Tomcat possui um JNDI somente leitura, assim o Weld não pode vincular automaticamente a extensão SPI do BeanManager. Para vincular o BeanManager ao JNDI, você deve preencher META-INF/context.xml
na raiz web com o seguinte conteúdo:
<Context>
<Resource name="BeanManager"
auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context
>
e torná-lo disponível para a sua implantação, acrescentando isto no final do web.xml
:
<resource-env-ref>
<resource-env-ref-name
>BeanManager</resource-env-ref-name>
<resource-env-ref-type>
javax.enterprise.inject.spi.BeanManager
</resource-env-ref-type>
</resource-env-ref
>
O Tomcat somente permite que você vincule entradas em java:comp/env
, assim o BeanManager estará disponível em java:comp/env/BeanManager
Weld também suporta injeção de Servlet no Tomcat 6.
Como o Tomcat, o Jetty possui um JNDI somente leitura, assim o Weld não pode vincular automaticamente o BeanManager. Para vincular o BeanManager ao JNDI no Jetty 6, você deve preencher WEB-INF/jetty-env.xml
com o seguinte conteúdo:
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
"http://jetty.mortbay.org/configure.dtd">
<Configure id="webAppCtx" class="org.mortbay.jetty.webapp.WebAppContext">
<New id="BeanManager" class="org.mortbay.jetty.plus.naming.Resource">
<Arg
><Ref id="webAppCtx"/></Arg
>
<Arg
>BeanManager</Arg>
<Arg>
<New class="javax.naming.Reference">
<Arg
>javax.enterprise.inject.spi.BeanManager</Arg
>
<Arg
>org.jboss.weld.resources.ManagerObjectFactory</Arg>
<Arg/>
</New>
</Arg>
</New>
</Configure
>
O Jetty 7 foi movido para a Fundação Eclipse; se você está usando o Jetty 7 coloque o seguinte conteúdo em seu WEB-INF/jetty-env.xml
:
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
"http://www.eclipse.org/jetty/configure.dtd">
<Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext">
<New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg
> <Ref id="webAppCtx"/> </Arg>
<Arg
>BeanManager</Arg>
<Arg>
<New class="javax.naming.Reference">
<Arg
>javax.enterprise.inject.spi.BeanManager</Arg>
<Arg
>org.jboss.weld.resources.ManagerObjectFactory</Arg>
<Arg/>
</New>
</Arg>
</New>
</Configure
>
Assim como no Tomcat, você precisa torná-lo disponível em sua implantação, acrescentando isto ao final do web.xml
:
<resource-env-ref>
<resource-env-ref-name
>BeanManager</resource-env-ref-name>
<resource-env-ref-type>
javax.enterprise.inject.spi.BeanManager
</resource-env-ref-type>
</resource-env-ref
>
Note que o Jetty não possui suporte já existente a um javax.naming.spi.ObjectFactory
como o Tomcat, assim é necessário criar manualmente o javax.naming.Reference
para envolvê-lo.
O Jetty somente permite que você vincule entradas em java:comp/env
, assim o BeanManager estará disponível em java:comp/env/BeanManager
O Weld também suporta injeção em Servlet no Jetty 6. Para habilitar isto, adicione o arquivo META-INF/jetty-web.xml
com o seguinte conteúdo em seu war:
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
"http://jetty.mortbay.org/configure.dtd">
<Configure id="webAppCtx" class="org.mortbay.jetty.webapp.WebAppContext">
<Call class="org.jboss.weld.environment.jetty.WeldServletHandler" name="process">
<Arg
><Ref id="webAppCtx"/></Arg>
</Call>
</Configure
>
Em adição a uma integração melhorada da pilha Java Enterprise, a especificação "Contexts and Dependency Injection for the Java EE platform" também define um framework de injeção de dependência em estado da arte e typesafe, o qual pode se comprovar útil em uma ampla variedade de tipos de aplicação. Para ajudar desenvolvedores tirar vantagem disto, o Weld fornece um meio simples de ser executado no ambiente Java Standard Edition (SE) independentemente de qualquer API da Java EE.
Quando executando no ambiente SE as seguintes funcionalidades do Weld estão disponíveis:
Managed beans com os callbacks @PostConstruct
e @PreDestroy
do ciclo de vida
Injeção de dependência com qualificadores e alternativos
Os escopos @Application
, @Dependent
e @Singleton
Interceptadores e decoradores
Estereótipos
Eventos
Suporte a extensão portável
Beans EJB não são suportados.
O Weld fornece uma extensão que inicializa um gerenciador de beans CDI em Java SE, registrando automaticamente todos os beans simples encontrados no classpath. Os parâmetros de linha de comando podem ser injetados usando uma das seguintes formas:
@Inject @Parameters List<String
> params;
@Inject @Parameters String[] paramsArray;
A segunda forma é útil para compatibilidade com classes existentes.
Os parâmetros de linha de comando não ficaram disponíveis para injeção até que o evento ContainerInitialized
seja disparado. Se você precisa acessar os parâmetros durante a inicialização você pode fazer assim por meio do método public static String[] getParameters()
em StartMain
.
Aqui está um exemplo de uma simples aplicação CDI SE:
@Singleton
public class HelloWorld
{
public void printHello(@Observes ContainerInitialized event, @Parameters List<String
> parameters) {
System.out.println("Hello " + parameters.get(0));
}
}
Aplicações CDI SE podem ser inicializadas das seguintes maneiras.
Devido ao poder do modelo de eventos typesafe de CDI, desenvolvedores de aplicação não precisam escrever qualquer código de inicialização. O módulo Weld SE vem com um método main embutido que inicializa o CDI para você e então dispara um evento ContainerInitialized
. O ponto de entrada para o código de sua aplicação seria, portanto, um simples bean que observa o evento ContainerInitialized
, como no exemplo anterior.
Neste caso sua aplicação pode ser iniciada chamando o método main fornecido como este:
java org.jboss.weld.environment.se.StartMain <args
>
Para adicionar flexibilidade, CDI SE também vem com uma API de inicialização que pode ser chamada dentro de sua aplicação para inicializar a CDI e obter referências para os beans e eventos de sua aplicação. A API consiste em duas classes: Weld
e WeldContainer
.
public class Weld
{
/** Boots Weld and creates and returns a WeldContainer instance, through which
* beans and events can be accesed. */
public WeldContainer initialize() {...}
/** Convenience method for shutting down the container. */
public void shutdown() {...}
}
public class WeldContainer
{
/** Provides access to all beans within the application. */
public Instance<Object
> instance() {...}
/** Provides access to all events within the application. */
public Event<Object
> event() {...}
/** Provides direct access to the BeanManager. */
public BeanManager getBeanManager() {...}
}
Aqui está um método main da aplicação de exemplo que usa esta API para inicializar um bean do tipo MyApplicationBean
.
public static void main(String[] args) {
WeldContainer weld = new Weld().initialize();
weld.instance().select(MyApplicationBean.class).get();
weld.shutdown();
}
Alternativamente a aplicação poderia ser iniciada ao disparar um evento personalizado que, então, seria observado por um outro simples bean. O seguinte exemplo dispara MyEvent
na inicialização.
public static void main(String[] args) {
WeldContainer weld = new Weld().initialize();
weld.event().select(MyEvent.class).fire( new MyEvent() );
weld.shutdown();
}
Em contraste com aplicações Java EE, aplicações Java SE coloca nenhuma restrição aos desenvolvedores a respeito da criação e uso de threads. Por isso o Weld SE fornece uma anotação de escopo específico, @ThreadScoped
, e uma correspondente implementação de contexto que pode ser usada para vincular instâncias de beans à thread corrente. É destinada a ser usada em cenários onde você poderia usar ThreadLocal
, e de fato fará uso de ThreadLocal
, mas por baixo dos panos.
Para usar a anotação @ThreadScoped você precisa habilitar o RunnableDecorator
que 'ouve' todas as execuções de Runnable.run()
e decora elas configurando o contexto de thread antecipadamente, delimitando a thread corrente e destruindo o contexto mais tarde.
<beans>
<decorators>
<decorator
>org.jboss.weld.environment.se.threading.RunnableDecorator</decorator>
</decorator>
</beans
>
Não é necessário usar @ThreadScoped em todas aplicações multithreaded. O contexto de thread não é destinado como um substituição a definir seus próprios cotextos específicos da aplicação. Somente é geralmente útil em situações onde você teria utilizado ThreadLocal diretamente, as quais são tipicamente raras.
O Weld SE vem empacotado como um jar 'iluminado' que inclui a API CDI, o Weld Core e todas classes dependentes agrupadas em um único jar. Por esse motivo o único jar do Weld que você precisa no classpath, em adição às classes e jars dependentes de sua aplicação, é o jar do Weld SE. Se você está trabalhando com uma aplicação Java SE pura você lançará ela usando java
e isto pode ser mais simples para você.
Se você prefere trabalhar com dependências individuais, então você pode usar o jar weld-core
que contém apenas as classes do Weld SE. Certamente neste modo você precisará montar o classpath você mesmo. Este modo é útil, por exemplo, se você deseja usar um slf4j alternativo.
Se você trabalha com uma solução de gerenciamento de dependências como o Maven, você pode declarar uma dependência com org.jboss.weld.se:weld-se-core
.