Meera Subbarao说道:EJB和Spring社区的开发者为什么总是贬低对方呢?我同时使用EJB和Spring,就像所有的开发者一样,我对于两者需要大量的XML设置非常头疼,但是从Java 5发布以来,XML配置已经用annotation来替代了。但是在使用了最新的Spring 2.5和EJB 3.0,我觉得它们是互相补充的关系,而非相互竞争关系。
许多开发者理解,Spring是由Spring Source创建的最常用的非标准框架,而EJB 3.0是一个由主要的JEE厂商创建的规格。我以前曾一起工作的同事更愿意使用标准规格,选择EJB 2.X现在迁移到EJB 3.0。也有开发者愿意使用Spring而拒绝EJB。但是没有任何东西阻止开发者同时使用Spring和EJB,对不对?在Spring的配置文件增加几行就能够在Spring中无缝使用EJB 3.0组件。
下面我将展示这个过程是多么简单,我们可以通过Spring的强大的依赖注入机制来注入Customer session bean。这个Customer session bean可以使用Entity Manager来进行创建/读写/删除操作。
1。创建一个简单的JPA Entity:
package com.ejb.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
*
* @author meerasubbarao
*/
@Entity
@Table(name = "CUSTOMER", catalog = "", schema = "ADMIN")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "CUSTOMER_ID")
private Long customerId;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "MIDDLE_NAME")
private String middleName;
@Column(name = "EMAIL_ID")
private String emailId;
public Customer() {
}
public Customer(Long customerId) {
this.customerId = customerId;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
2.创建一个EJB 3.0 Session bean.
The Interface:
package com.ejb.service;
import com.ejb.domain.Customer;
import java.util.Collection;
import javax.ejb.Remote;
/**
*
* @author meerasubbarao
*/
@Remote
public interface CustomerService {
Customer create(Customer info);
Customer update(Customer info);
void remove(Long customerId);
Collection<Customer> findAll();
Customer[] findAllAsArray();
Customer findByPrimaryKey(Long customerId);
}
The Implementation Class:
package com.ejb.service;
import com.ejb.domain.Customer;
import java.util.Collection;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.jws.WebMethod;
/**
*
* @author meerasubbarao
*/
@WebService(name = "CustomerService", serviceName = "CustomerService", targetNamespace = "urn:CustomerService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
@Stateless(name = "CustomerService")
public class CustomerServiceImpl implements CustomerService {
@PersistenceContext
private EntityManager manager;
@WebMethod
public Customer create(Customer info) {
this.manager.persist(info);
return info;
}
@WebMethod
public Customer update(Customer info) {
return this.manager.merge(info);
}
@WebMethod
public void remove(Long customerId) {
this.manager.remove(this.manager.getReference(Customer.class, customerId));
}
public Collection<Customer> findAll() {
Query query = this.manager.createQuery("SELECT c FROM Customer c");
return query.getResultList();
}
@WebMethod
public Customer[] findAllAsArray() {
Collection<Customer> collection = findAll();
return (Customer[]) collection.toArray(new Customer[collection.size()]);
}
@WebMethod
public Customer findByPrimaryKey(Long customerId) {
return (Customer) this.manager.find(Customer.class, customerId);
}
}
3.编译,打包,部署到一个应用服务器上。
我使用GlassFish,用缺省的持久化提供工具TopLink,persistence.xml文件配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="SpringAndEJBPU" transaction-type="JTA">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<jta-data-source>spring-ejb</jta-data-source>
<properties>
<property name="toplink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
当你的应用部署以后,确认session bean JNDI名称,在 GlassFish 中,点击JNDI浏览工具按钮查看:
4: 测试无状态 Session beans.
5: 创建一个 Spring Bean.
创建一个CustomerManager 接口:
package com.spring.service;
import com.ejb.domain.Customer;
/**
*
* @author meerasubbarao
*/
public interface CustomerManager {
public void addCustomer(Customer customer);
public void removeCustomer(Long customerId);
public Customer[] listCustomers();
}
package com.spring.service;
import com.ejb.domain.Customer;
import com.ejb.service.CustomerService;
/**
*
* @author meerasubbarao
*/
public class CustomerManagerImpl implements CustomerManager {
CustomerService customerService;
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}
public void removeCustomer(Long customerId) {
customerService.remove(customerId);
}
public Customer[] listCustomers() {
return customerService.findAllAsArray();
}
public void addCustomer(Customer customer) {
customerService.create(customer);
}
}
6: 注入 EJB 3.0 Session bean 进入我们的 Spring Beans.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
<jee:jndi-lookup id="customerService" <b>jndi-name="com.ejb.service.CustomerService"</b>>
</jee:jndi-lookup>
<bean id="manageCustomer"
class="com.spring.service.CustomerManagerImpl">
<property name="customerService" ref="customerService" />
</bean>
</beans>
<jee:jndi-lookup id="customerService" jndi-name="com.ejb.service.CustomerService">
</jee:jndi-lookup>
<bean id="manageCustomer"
class="com.spring.service.CustomerManagerImpl">
<property name="customerService" ref="customerService" />
</bean>
7: 测试
package com.spring.client;
import com.ejb.domain.Customer;
import com.spring.service.CustomerManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringAndEJBMain {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("SpringXMLConfig.xml");
CustomerManager service = (CustomerManager) context.getBean("manageCustomer");
Customer customer = new Customer();
customer.setFirstName("Meera");
customer.setLastName("Subbarao");
customer.setMiddleName("B");
customer.setEmailId("meera@springandejb.com");
customer.setCustomerId(new Long(1));
service.addCustomer(customer);
for (Customer cust : service.listCustomers()) {
System.out.println(cust.getFirstName());
System.out.println(cust.getLastName());
System.out.println(cust.getMiddleName());
System.out.println(cust.getEmailId());
}
service.removeCustomer(new Long(1));
}
}
整个过程结束,使用Spring和EJB 3.0能够同时或者两者的好处。
11 楼 zhuchao_ko 2011-06-14 17:14
之后你们问的问题都不是问题。OK?
10 楼 darkkid00 2010-10-14 20:48
EJB提供分布式组建,spring自动访问EJB组建,为客户端组建解耦
9 楼 linzewu100 2010-07-06 15:47
8 楼 taxuewuhen 2009-04-02 14:21
7 楼 jameswallace 2008-10-13 11:02
6 楼 zhongxun20 2008-09-03 13:00
5 楼 xiaopang106 2008-09-02 17:22
4 楼 xiaoqulai 2008-09-01 17:58
avax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.XWS_ClientProvider.property.signature.key.alias" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "domain.applications.lifecycle-module.JBIFramework.property.com.sun.jbi.home" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.XWS_ServerProvider.property.encryption.key.alias" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.ClientProvider.property.security.config" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.ClientProvider.property.encryption.key.alias" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.ServerProvider.property.security.config" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.applications.lifecycle-module.JBIFramework.property.com.sun.jbi.home" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.ClientProvider.property.dynamic.username.password" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.ServerProvider.property.signature.key.alias" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.XWS_ClientProvider.property.dynamic.username.password" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.XWS_ClientProvider.property.encryption.key.alias" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.ClientProvider.property.signature.key.alias" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.ServerProvider.property.encryption.key.alias" 匹配的对象
javax.management.InstanceNotFoundException: 没有与指定的名称 "server.security-service.message-security-config.SOAP.provider-config.XWS_ServerProvider.property.signature.key.alias" 匹配的对象
Why?
3 楼 janmy 2008-08-30 20:47
2 楼 Acaleph 2008-08-30 07:45
批评和指责,有助于进步。
这只是从应用层面,做了个使用例子,实际项目开发过程中,要考虑的东西还是很多的。
1 楼 key232323 2008-08-29 18:48