blob: 50e9ffa68c542914673c249480e010e3c0fc3c04 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apache TomEE</title>
<meta name="description"
content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
<meta name="author" content="Luka Cvetinovic for Codrops" />
<link rel="icon" href="../../../favicon.ico">
<link rel="icon" type="image/png" href="../../../favicon.png">
<meta name="msapplication-TileColor" content="#80287a">
<meta name="theme-color" content="#80287a">
<link rel="stylesheet" type="text/css" href="../../../css/normalize.css">
<link rel="stylesheet" type="text/css" href="../../../css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../../../css/owl.css">
<link rel="stylesheet" type="text/css" href="../../../css/animate.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/eleganticons/et-icons.css">
<link rel="stylesheet" type="text/css" href="../../../css/jqtree.css">
<link rel="stylesheet" type="text/css" href="../../../css/idea.css">
<link rel="stylesheet" type="text/css" href="../../../css/cardio.css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2717626-1']);
_gaq.push(['_setDomainName', 'apache.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="preloader">
<img src="../../../img/loader.gif" alt="Preloader image">
</div>
<nav class="navbar">
<div class="container">
<div class="row"> <div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>
<img src="../../../img/logo-active.png">
</span>
Apache TomEE
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right main-nav">
<li><a href="../../../docs.html">Documentation</a></li>
<li><a href="../../../community/index.html">Community</a></li>
<li><a href="../../../security/security.html">Security</a></li>
<li><a href="../../../download-ng.html">Downloads</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div></div>
</div>
<!-- /.container-fluid -->
</nav>
<div id="main-block" class="container main-block">
<div class="row title">
<div class="col-md-12">
<div class='page-header'>
<h1>Alternativas e Estereótipos do CDI</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="sect1">
<h2 id="_introdução">Introdução</h2>
<div class="sectionbody">
<div class="paragraph">
<p>CDI é uma revolução para o mundo Java EE. Está especificação é a melhor para evitar acoplamento entre classes.</p>
</div>
<div class="paragraph">
<p>Este exemplo simplesmente pretende substituir ligações em tempo de execução para simplificar o trabalho de mocking.</p>
</div>
<div class="paragraph">
<p>Aqui usamos dois tipos de mocks:</p>
</div>
<div class="paragraph">
<p>1) um mock com nenhuma implementação no classloader</p>
</div>
<div class="paragraph">
<p>2) um mock com uma implementação no classloader</p>
</div>
<div class="paragraph">
<p>A resposta mock do CDI é chamada de <em>alternative</em>.</p>
</div>
<div class="paragraph">
<p>Anotando com o <code>@Alternative</code> uma classe significa que será usado como implementação se não houver outra implementação
ou se for forçado (através do <code>META-INF/beans.xml</code>).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_explicação_do_código">Explicação do Código</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_código_principal">Código Principal</h3>
<div class="paragraph">
<p>Nós usamos um EJB <code>Journey</code> para modelar um journey onde o vehicle e society pode mudar. Aqui um EJB é usado
por que isto simplifica o teste. Uma journey envolve a informação de vehicle e society .</p>
</div>
<div class="paragraph">
<p>Nós definimos duas interfaces para injetar no EJB <code>Journey</code>:` Vehicle` e <code>Society</code>.</p>
</div>
<div class="paragraph">
<p>Finalmente, adicionamos uma implementação para a interface <code>Society</code>:` LowCostCompanie`.</p>
</div>
<div class="paragraph">
<p>Se paramos aqui, o objeto <code>Journey</code> não poderá ser criado porque não há uma implementação <code>Vehicle</code> acessível.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
se tivermos uma implementação de <code>Vehicle</code>, a Society injetada deverá ser <code>LowCostCompanie</code>.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_código_de_teste">Código de Teste</h3>
<div class="paragraph">
<p>O objetivo aqui é para testar o nosso EJB <code>Journey</code>. Portanto, temos que fornecer uma implementação de <code>Vehicle</code>:` SuperCar`.</p>
</div>
<div class="paragraph">
<p>Queremos forçar a interface <code>Society</code> a ser a implementação do <code>AirOpenEJB</code> para o nosso teste.</p>
</div>
<div class="paragraph">
<p>Uma solução poderia ser simplesmente adicionar a anotação <code>@ Alternative</code> no` AirOpenEJB` e ativá-la através do
arquivo <code>META-INF / beans.xml</code>.</p>
</div>
<div class="paragraph">
<p>Aqui queremos escrever um código mais explícito. Então, queremos substituir a anotação <code>@Alternative</code> por uma` <code>@Mock</code>.</p>
</div>
<div class="paragraph">
<p>Então nós definimos uma anotação <code>@Mock</code> para classes, resolvíveis em tempo de execução como um estereótipo (` @Stereotype`)
que substitui o <code>@Alternative</code>.</p>
</div>
<div class="paragraph">
<p>Aqui a anotação:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> @Stereotype // we define a stereotype
@Retention(RUNTIME) // resolvable at runtime
@Target(TYPE) // this annotation is a class level one
@Alternative // it replace @Alternative
public @interface Mock {}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
você pode adicionar mais anotações CDI após <code>@Alternative</code> e obterá o comportamento esperado (o escopo para a instância).
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Então agora temos a nossa anotação <code>@ Mock</code>, que é um estereótipo capaz de substituir a anotação` @ Alternative` quando
adicionado às nossas mocks.</p>
</div>
<div class="paragraph">
<p>Se você executar isso agora, nós receberemos está exceção:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> jakarta.enterprise.inject.UnsatisfiedResolutionException: Api type [org.superbiz.cdi.stereotype.Vehicle] is not found with the qualifiers
Qualifiers: [@jakarta.enterprise.inject.Default()]
for injection into Field Injection Point, field name : vehicle,
Bean Owner : [Journey, Name:null, WebBeans Type:ENTERPRISE, API Types:[java.lang.Object,org.superbiz.cdi.stereotype.Journey],
Qualifiers:[jakarta.enterprise.inject.Any,jakarta.enterprise.inject.Default]]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Isso significa que o estereótipo não está ativado. Para fazer isso basta adicioná-lo ao seu <code>META-INF / beans.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre> &lt;alternatives&gt;
&lt;stereotype&gt;org.superbiz.cdi.stereotype.Mock&lt;/stereotype&gt;
&lt;/alternatives&gt;</pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
se você não especificar <code>AirOpenEJB</code> como` @ Alternative` (feito através de nossa anotação mock) você receberá está exceção:
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> Caused by: jakarta.enterprise.inject.AmbiguousResolutionException:
There is more than one api type with : org.superbiz.cdi.stereotype.Society with qualifiers :
Qualifiers: [@jakarta.enterprise.inject.Default()] for injection into Field Injection Point, field name : society,
Bean Owner : [Journey, Name:null, WebBeans Type:ENTERPRISE,
API Types:[org.superbiz.cdi.stereotype.Journey,java.lang.Object],
Qualifiers:[jakarta.enterprise.inject.Any,jakarta.enterprise.inject.Default]]
found beans:
AirOpenEJB, Name:null, WebBeans Type:MANAGED,
API Types:[org.superbiz.cdi.stereotype.Society,org.superbiz.cdi.stereotype.AirOpenEJB,java.lang.Object],
Qualifiers:[jakarta.enterprise.inject.Any,jakarta.enterprise.inject.Default]
LowCostCompanie, Name:null, WebBeans Type:MANAGED,
API Types:[org.superbiz.cdi.stereotype.Society,org.superbiz.cdi.stereotype.LowCostCompanie,java.lang.Object],
Qualifiers:[jakarta.enterprise.inject.Any,jakarta.enterprise.inject.Default]</code></pre>
</div>
</div>
<div class="paragraph">
<p>o que significa simplesmente que duas implementações estão disponíveis para o mesmo ponto de injeção (<code>Journey.society</code>).</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_conclusão">Conclusão</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Com o CDI é realmente fácil definir anotações com um forte significado. Você pode definir anotações de negócios
ou simplesmente anotações técnicas para simplificar seu código (como fizemos com a anotação mock).</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
se você usou qualificadores para injetar objetos <code>Society</code> você poderia ter colocado todos esses qualificadores em
a classe mock ou definiu uma anotação <code>@SocietyMock</code> para poder injetar a mesma implementação para
todos os qualificadores em seus testes.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_saída">Saída</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre> Running org.superbiz.cdi.stereotype.StereotypeTest
Apache OpenEJB 7.0.0-SNAPSHOT build: 20111030-07:54
http://tomee.apache.org/
INFO - openejb.home = /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes
INFO - openejb.base = /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes
INFO - Using 'jakarta.ejb.embeddable.EJBContainer=true'
INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
INFO - Found EjbModule in classpath: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/test-classes
INFO - Found EjbModule in classpath: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/classes
INFO - Beginning load: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/test-classes
INFO - Beginning load: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/classes
INFO - Configuring enterprise application: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes
INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container)
INFO - Auto-creating a container for bean cdi-alternative-and-stereotypes_test.Comp: Container(type=MANAGED, id=Default Managed Container)
INFO - Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container)
INFO - Auto-creating a container for bean Journey: Container(type=SINGLETON, id=Default Singleton Container)
INFO - Enterprise application "/opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes" loaded.
INFO - Assembling app: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes
INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes_test.Comp!org.apache.openejb.BeanContext$Comp")
INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes_test.Comp")
INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes.Comp!org.apache.openejb.BeanContext$Comp")
INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes.Comp")
INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/Journey!org.superbiz.cdi.stereotype.Journey")
INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/Journey")
INFO - Jndi(name="java:global/EjbModule162291475/org.superbiz.cdi.stereotype.StereotypeTest!org.superbiz.cdi.stereotype.StereotypeTest")
INFO - Jndi(name="java:global/EjbModule162291475/org.superbiz.cdi.stereotype.StereotypeTest")
INFO - Created Ejb(deployment-id=cdi-alternative-and-stereotypes_test.Comp, ejb-name=cdi-alternative-and-stereotypes_test.Comp, container=Default Managed Container)
INFO - Created Ejb(deployment-id=cdi-alternative-and-stereotypes.Comp, ejb-name=cdi-alternative-and-stereotypes.Comp, container=Default Managed Container)
INFO - Created Ejb(deployment-id=org.superbiz.cdi.stereotype.StereotypeTest, ejb-name=org.superbiz.cdi.stereotype.StereotypeTest, container=Default Managed Container)
INFO - Created Ejb(deployment-id=Journey, ejb-name=Journey, container=Default Singleton Container)
INFO - Started Ejb(deployment-id=cdi-alternative-and-stereotypes_test.Comp, ejb-name=cdi-alternative-and-stereotypes_test.Comp, container=Default Managed Container)
INFO - Started Ejb(deployment-id=cdi-alternative-and-stereotypes.Comp, ejb-name=cdi-alternative-and-stereotypes.Comp, container=Default Managed Container)
INFO - Started Ejb(deployment-id=org.superbiz.cdi.stereotype.StereotypeTest, ejb-name=org.superbiz.cdi.stereotype.StereotypeTest, container=Default Managed Container)
INFO - Started Ejb(deployment-id=Journey, ejb-name=Journey, container=Default Singleton Container)
INFO - Deployed Application(path=/opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes)
INFO - Undeploying app: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-6 text-center-mobile">
<h3 class="white">Be simple. Be certified. Be Tomcat.</h3>
<h5 class="light regular light-white">"A good application in a good server"</h5>
<ul class="social-footer">
<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
<li><a href="https://plus.google.com/communities/105208241852045684449"><i class="fa fa-google-plus"></i></a></li>
</ul>
</div>
<div class="col-sm-6 text-center-mobile">
<div class="row opening-hours">
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/docs/" class="white">Documentation</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
<li><a href="../../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
<li><a href="../../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
<li><a href="../../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/examples/" class="white">Examples</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
<li><a href="../../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
<li><a href="../../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
<li><a href="../../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../community/index.html" class="white">Community</a></h5>
<ul class="list-unstyled">
<li><a href="../../../community/contributors.html" class="regular light-white">Contributors</a></li>
<li><a href="../../../community/social.html" class="regular light-white">Social</a></li>
<li><a href="../../../community/sources.html" class="regular light-white">Sources</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../security/index.html" class="white">Security</a></h5>
<ul class="list-unstyled">
<li><a href="http://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
<li><a href="http://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
<li><a href="http://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row bottom-footer text-center-mobile">
<div class="col-sm-12 light-white">
<p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
</div>
</div>
</div>
</footer>
<!-- Holder for mobile navigation -->
<div class="mobile-nav">
<ul>
<li><a hef="../../../latest/docs/admin/index.html">Administrators</a>
<li><a hef="../../../latest/docs/developer/index.html">Developers</a>
<li><a hef="../../../latest/docs/advanced/index.html">Advanced</a>
<li><a hef="../../../community/index.html">Community</a>
</ul>
<a href="#" class="close-link"><i class="arrow_up"></i></a>
</div>
<!-- Scripts -->
<script src="../../../js/jquery-1.11.1.min.js"></script>
<script src="../../../js/owl.carousel.min.js"></script>
<script src="../../../js/bootstrap.min.js"></script>
<script src="../../../js/wow.min.js"></script>
<script src="../../../js/typewriter.js"></script>
<script src="../../../js/jquery.onepagenav.js"></script>
<script src="../../../js/tree.jquery.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/main.js"></script>
</body>
</html>