黄页网络的推广网站有哪些好,手工制作书签,唐山彩钢中企动力提供网站建设,备案号如何绑定多个网站我最近在一个非常复杂的项目中工作#xff0c;其中融合了许多Java EE 6技术#xff08;例如JPA#xff0c;JAXB#xff0c;JMS#xff0c;JTA#xff0c;JAX-RS等#xff09;。 出于生产力和计划方面的原因#xff0c;将原型应用程序设计为独立的纯Spring应用程序。 当… 我最近在一个非常复杂的项目中工作其中融合了许多Java EE 6技术例如JPAJAXBJMSJTAJAX-RS等。 出于生产力和计划方面的原因将原型应用程序设计为独立的纯Spring应用程序。 当实际应用程序的开发开始时我们重新挑战了最初的选择即Spring v3并分析了切换到Java EE 6应用服务器例如GlassFish或JBoss的兴趣。 这最终导致两个主要问题 我们可以在Java EE 6中完成Spring可以做的一切吗 我们可以像在Spring那样简单吗 好吧我要说的是在全球范围内答案是是的我们可以 我不想重新开始无休止的辩论要知道在Spring和Java EE 6之间哪个是最好的。 不我只想与您分享我有关迁移的经验。 我曾经是现在仍然是一个真正的Spring狂热爱好者从历史上来说我是在EJB 1.0令人反感之后才发现的但我也知道最近在Linux中引入的进展而不仅仅是简化。这些年来的Java EE以及Java EE 6应用程序服务器方面令人印象深刻的速度改进。 现在让我们详细研究“企业”应用程序的一些典型要求并比较在两种情况下要产生的代码 上下文和依赖注入 讯息传递 交易管理 网页服务 如果您不愿从一种技术迁移到另一种技术那么这种比较应该为您提供一些具体的决策要素…… 第一部分上下文和依赖注入CDI Spring允许您使用各种构造型例如 Repository Service Controller和Component定义bean。 选择的选项不是那么重要这不是完全正确。例如将DAO标记为Repository将添加SQL异常的自动翻译因为这种区别主要是针对IDE的以便对bean进行分类。 可选您可以为您的bean命名。 public interface MyInterface {...}import org.springframework.stereotype.Component;Component(firstBean)
public class MySpringBean implements MyInterface {...}Component(firstBeanMock)
public class MockImpl implements MyInterface {...} Java EE提供了非常相似的注释Named但其使用应仅限于纯pojo。 如果是面向服务的Bean尤其是事务性粗粒度服务请考虑使用最好是无状态的EJB即因为它们提供了更好的可伸缩性。 import javax.inject.Named;Named(firstBean)
public class MyJeeBean implements MyInterface {...}import javax.ejb.Stateless;Stateless(namefirstService)
public class MyJeeService implements MyInterface {...} 还应注意与Spring相反应在Java EE中将单例显式标记为 import javax.inject.Singleton;Singleton
public class MyJeeSingleton implements MyInterface {...} 备注在“ javax.inject.Singleton”和“ javax.ejb.Singleton”之间进行选择时您可能会感到困惑。 第一个定义由容器在Java EE世界中也称为“ Managed Bean ”管理的标准POJO而第二个定义“ Enterprise Bean”。 请记住后者是为并发访问而设计的客户端无需担心可能同时调用单例相同方法的任何其他客户端并且还提供了事务管理功能请参阅进一步。 现在我们已经注册了并可以选择命名我们的bean我们可以将它们注入其他bean中。 再一次双方的程序有点类似 弹簧 import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;Component
public class UseCaseHandler {AutowiredQualifier(firstBean)private MyInterface serviceFacade;} JAVA EE 6 import javax.inject.Named;
import javax.inject.Inject;Named
public class UseCaseHandler {InjectNamed(firstBean) private MyInterface serviceFacade;} 备注JSR-330统一了注入托管bean的方式。 具体来说这意味着Inject批注可用于注入简单的POJO和EJB从而使EJB批注过时。 很好 但是在现实世界中我们要注入的bean的名称例如“ firstBean”可能是动态的。 当您使用行为模式泛型等时尤其如此。 在Spring这非常容易。 例如您可以使您的bean能够识别ApplicationContext以便随后可以使用注入的Spring上下文来查找特定的bean实例 import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;import com.javacodegeeks.Request;Service
public class Dispatcher implements ApplicationContextAware {private ApplicationContext appContext;public void setApplicationContext(ApplicationContext ctx) throws BeansException {appContext ctx;}public void dispatch(Request request) throws Exception {String beanName requestHandler_ request.getRequestTypeId();RequestHandler myHandler appContext.getBean(beanName, RequestHandler.class);myHandler.handleRequest(request);}}public interface RequestHandler {public void handleRequest(Request request);
}Component(requestHandler_typeA)
public class HandlerA implements RequestHandler {...}Component(requestHandler_typeB)
public class HandlerB implements RequestHandler {...} 在Java EE 6中这是可能的但是需要更多的代码行可以集中在帮助程序类中 import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;import com.javacodegeeks.Request;Named
public class Dispatcher Injectprivate BeanManager beanManager;public void dispatch(Request request) throws Exception {String beanName requestHandler_ request.getRequestTypeId();RequestHandler myHandler this.getBean(beanName, RequestHandler.class);myHandler.handleRequest(request);}SuppressWarnings(unchecked)private T T getBean(String name, ClassT clazz) throws Exception {SetBean? founds beanManager.getBeans(name);if ( founds.size()0 ) {throw new Exception(No such bean found: name);} else {BeanT bean (BeanT) founds.iterator().next();CreationalContextT cc beanManager.createCreationalContext(bean);T instance (T) beanManager.getReference(bean, clazz, cc);return instance;}}}public interface RequestHandler {public void handleRequest(Request request);
}Named(requestHandler_typeA)
public class HandlerA implements UseCaseHandler {…}Named(requestHandler_typeB)
public class HandlerB implements UseCaseHandler {...}第二部分JMS Java Messaging Service简化了松散耦合的分布式通信的实现。 这就是为什么它已成为企业应用程序集成EAI中的经典技术的原因。 Spring具有出色的JMS支持。 您可以非常快速地设置JMS生产者或使用者 使用目标解析器还可以选择将JMS消息自动转换为pojos反之亦然。 另一方面J2EE带有一组丰富的注释以便访问或定义JMS资源例如队列/主题连接或面向消息的Bean。 让我们从接收消息的JMS客户端开始该客户端是消息使用者或订户 弹簧 bean idjndiTemplate classorg.springframework.jndi.JndiTemplateproperty nameenvironmentprops…/props/property
/beanbean idjmsConnectionFactory classorg.springframework.jndi.JndiObjectFactoryBeanproperty namejndiTemplate refjndiTemplate /property namejndiName valuejava:/JmsXA /
/beanbean idjndiDestResolverclassorg.springframework.jms.support.destination.JndiDestinationResolverproperty namejndiTemplate refjndiTemplate /
/beanbean idjmsContainerclassorg.springframework.jms.listener.DefaultMessageListenerContainerproperty nameconnectionFactory refjmsConnectionFactory/ property namedestinationResolver refjndiDestResolver/ property namedestinationName valuequeue/myQueue/property namemessageListener refmyMsgConsumer /
/beanbean idmyMsgConverter classcom.javacodegeeks.MsgToRequestConverter/bean idmyMsgConsumer classcom.javacodegeeks.MsgConsumer/import javax.jms.Message;
import javax.jms.MessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.support.converter.MessageConverter;import com.javacodegeeks.Request;
import com.javacodegeeks.Dispatcher;/*** Example of message consumer (Message-Driven-Pojo) in Spring*/
public class MsgConsumer implements MessageListener {Autowiredprivate MessageConverter msgConverter;Autowiredprivate Dispatcher dispatcher;public void onMessage(Message message) { try { Request request (Request) msgConverter.fromMessage(message);dispatcher.dispatch(request); } catch (Exception e) {e.printStackTrace(); } }} JAVA EE 6 import javax.inject.Inject;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.ejb.MessageDriven;
import javax.ejb.ActivationConfigProperty;import com.javacodegeeks.Request;
import com.javacodegeeks.Dispatcher ;
import com.javacodegeeks.MsgToRequestConverter;/*** Example of message consumer (Message-Driven-Bean) in JEE*/
MessageDriven(activationConfig { ActivationConfigProperty(propertyNamedestinationType, propertyValuejavax.jms.Queue),ActivationConfigProperty(propertyNamedestination, propertyValuequeue/myQueue)
} )
public class MsgConsumer implements MessageListener {Injectprivate MsgToRequestConverter msgConverter;Inject private Dispatcher dispatcher;public void onMessage(Message message) { try { Request request msgConverter.fromMessage(message);dispatcher.dispatch(request); } catch (Exception e) {e.printStackTrace(); } }} 现在让我们编写一个用于创建和发送消息的JMS客户端即消息生产者或发布者 弹簧 bean idjndiTemplate classorg.springframework.jndi.JndiTemplateproperty nameenvironmentprops…/props/property
/beanbean idjmsConnectionFactory classorg.springframework.jndi.JndiObjectFactoryBeanproperty namejndiTemplate refjndiTemplate /property namejndiName valuejava:/JmsXA /
/beanbean idjndiDestResolverclassorg.springframework.jms.support.destination.JndiDestinationResolverproperty namejndiTemplate refjndiTemplate /
/beanbean idjmsTemplate classorg.springframework.jms.core.JmsTemplateproperty nameconnectionFactory refjmsConnectionFactory /property namedestinationResolver refjndiDestResolver /property namemessageConverter refmyMsgConverter /
/beanbean idmyMsgConverter classcom.javacodegeeks.MsgConverterimport org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import com.javacodegeeks.Request;/*** Example of message producer component in Spring*/
Component
public class MsgProducer {Autowiredprivate JmsTemplate jmsTemplate;public void postRequest(Request request) throws Exception {jmsTemplate.convertAndSend(queue/myQueue, request);}} JAVA EE 6 import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.ejb.Stateless;
import javax.ejb.EJBException;import com.javacodegeeks.Request;
import com.javacodegeeks.MsgToRequestConverter;/*** Example of message producer (here a session bean) in JEE*/
Stateless(namemsgProducer)
public class MsgProducer {Injectprivate MsgToRequestConverter msgConverter;Resource(mappedNamejava:/JmsXA)private ConnectionFactory connectionFactory;Resource(mappedNamequeue/myQueue)private Queue queue;private Connection jmsConnection;PostConstructprivate void initialize() {try {jmsConnection connectionFactory.createConnection();} catch (JMSException e) {throw new EJBException(e);}}PreDestroyprivate void cleanup() {try {if (jmsConnection!null) jmsConnection.close();} catch (JMSException e) {throw new EJBException(e);}}public void postRequest(Request request) throws Exception { Session session null;MessageProducer producer null;try {session jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);producer session.createProducer(queue);Message msg msgConverter.toMessage(request, session);producer.send(msg); } finally { try { if (producer!null) producer.close();if (session!null) session.close();} catch (Exception e) {System.err.println(JMS session not properly closed: e);}}}} 备注 不要忘记与JMS连接和JMS队列相反JMS会话不是线程安全的。 因此会话不应由所有bean实例共享也不应在构造函数或PostConstruct方法中创建。 PostConstruct和PreDestroy方法应该只抛出运行时异常。 这就是为什么必须将JMS异常例如包装到EJB异常中的原因。 第三部分交易管理 事务的需求在系统体系结构中至关重要尤其是在SOA出现时。 在这样的体系结构中可以通过组装现有的可能还有交易的较小的服务“ 微服务 ”来构建粗粒度的交易服务。 Spring和Java EE都通过提供强大的声明式基于注释事务管理来满足这一需求。 弹簧 !-- Recognize Transactional annotations in our beans --
tx:annotation-driven transaction-managertxManager/!-- The transaction manager to use (here the JPA implementation) --
bean idtxManager classorg.springframework.orm.jpa.JpaTransactionManager...
/beanimport org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;import com.javacodegeeks.Request;
import com.javacodegeeks.RequestProcessor;Service
public class RequestProcessorImpl implements RequestProcessor {Transactional(propagationPropagation.REQUIRED, rollbackForException.class)public void process(Request request) throws Exception {...}} JAVA EE 6 import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;import com.javacodegeeks.Request;
import com.javacodegeeks.RequestProcessor;Stateless
TransactionManagement(valueTransactionManagementType.CONTAINER)
public class RequestProcessorImpl implements RequestProcessor {TransactionAttribute(TransactionAttributeType.REQUIRED)public void process(Request request) throws Exception {...}} 对Java EE中的运行时/未经检查的异常要非常小心。 默认情况下它们被EJB容器自动包装到EJBException中这可能会导致令人惊讶的结果尤其是在try…catch语句中。 如果您需要对回滚情况进行更好的调整请考虑使用ApplicationException批注或通过如下扩展ejb描述符将此类运行时异常标记为适用性异常 ejb-jarassembly-descriptorapplication-exceptionexception-classjava.lang.NullPointerException/exception-classrollbacktrue/rollback/application-exception/assembly-descriptor
/ejb-jar第四部分宁静的Web服务 企业应用程序通常需要通过Internet将其某些服务公开给外界。 这就是Web服务发挥作用的地方。 与JMS用于异步通信一样Web服务是另一种经典的集成技术用于使用XML或JSON作为交换格式实现面向请求响应的同步通信。 弹簧 servletservlet-namews/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class
/servlet
servlet-mappingservlet-namews/servlet-nameurl-pattern/services/*/url-pattern
/servlet-mapping!-- Dispatch requests to controllers use JAXB (if found in the classpath) --
mvc:annotation-driven /import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;import com.javacodegeeks.Geek;
import com.javacodegeeks.GeekService;Controller
RequestMapping(/geeks)
public class GeekWebService {AutowiredGeekService bizService;RequestMapping(value/{id}, methodRequestMethod.GET)ResponseBodypublic Geek getGeek(PathVariable(id) long geekId) {return bizService.findGeek(geekId);}}import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;XmlRootElement(namegeek)
public class Geek {private String name;private Long id;XmlElementpublic String getName() {return name;}public void setName(String name) {this.name name;}XmlAttributepublic Long getId() {return id;}public void setId(Long id) {this.id id;}} JAVA EE 6 import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;import com.javacodegeeks.Geek;
import com.javacodegeeks.GeekService;Path(/geeks)
Produces(MediaType.APPLICATION_XML)
public class GeekWebService {InjectGeekService bizService;GETPath(/{id})public Geek getGeek(PathParam(id) long geekId) {return bizService.findGeek(geekId);}}import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;XmlRootElement(namegeek)
public class Geek {private String name;private Long id;XmlElementpublic String getName() {return name;}public void setName(String name) {this.name name;}XmlAttributepublic Long getId() {return id;}public void setId(Long id) {this.id id;}} 备注一些JAX-RS实现例如JBoss RestEasy不需要修改web.xml即可配置和安装Web服务… 第五部分结论 认为与Java EE相比Spring中的事情要简单得多轻得多是不正确的。 这只是一个品味问题。 此外最近的Java EE 6应用服务器例如GlassFish 3或JBoss 6和7的启动速度非常快实际上几乎与Spring应用程序一样快。 然而从“同类最佳”的角度来看将两种技术结合起来可能仍然很有趣。 这将是我下一期JCG文章的主题-) 参考 从Spring到我们的W4G合作伙伴 Bernard Ligny的 Java EE 6 。 相关文章 什么是CDI它与EJB和Spring有什么关系 Spring Singleton请求会话Bean和线程安全 Devoxx 2011印象 Java EE6事件JMS的轻量级替代品 Java EE6 CDI命名组件和限定符 Java EE过去现在和云7 Java SE 7、8、9 –推进Java 翻译自: https://www.javacodegeeks.com/2011/11/from-spring-to-java-ee-6.html