1 什么是Spring
Spring是一个开源框架,它是为简化企业级系统开发而生的,由Rod Johnson大师创建。Spring正如其名,使开发者从EJB的繁琐中解脱出来,使企业级开发迎来了春天,感受到春天般的温暖。
1.1 Spring关键词
轻量: 主要从spring大小和处理开支来说的。
非侵入性: 使用spring一般不依赖于spring的类,当然为了使用一些特性,也会依赖于spring的类,但是不像其他框架那样,必须依赖框架的类。
IoC(控制反转):通过IoC实现对象之间的松耦合,对象之间的依赖关系交由spring容器,由spring容器负责将对象依赖的类注入给它。这是spring的核心概念。
AOP(面向切面编程):通过面向切面编程将业务逻辑和系统服务(例如事务,监控,日志等)分离开来,从而让业务逻辑更加简洁清晰。
容器:spring是一个容器,他管理着系统对象的生命周期和配置,配置对象之间的关联关系,但不像EJB容器那样笨重、庞大。
框架:spring是一个框架,它提供了很多基础服务,使用每个框架都会遵守框架的约定,有框架带有的特征。
1.2 Spring模块
[img]http://dl2.iteye.com/upload/attachment/0104/5682/dafc7fd0-8edf-3d49-bd06-ce5c20fbac54.jpg[/img]
--图片截自《spring in action 3rd》,虽然看到好几个版本的模块组成图,但是下面这几个核心的基本都包含。
核心spring容器:容器是spring框架的核心,负责Bean的创建、配置和管理。主要包括BeanFactory和ApplicationContext。
AOP模块:提供了面向切面编程。
数据访问和集成:spring的jdbcTemplate封装了创建连接,释放连接等样板式代码,使jdbc代码更加简洁。另外spring并不想重复发明轮子,他的ORM解决思想是让spring可以集成ORM框架,如Hibernate,iBATIS等。
Web和远程调用:spring提供了MVC框架,另外spring通过RMI,JAX-RPC和WebService提供远程调用代理。
2 Spring vs EJB
由于spring是简化企业级系统开发而生的,那么它必然带有许多企业级服务的支持,所以它被看做了EJB的替代者,但实际上他们二者是可以和平相处的,也可以共存。
spring和EJB功能比较表:
[img]http://dl2.iteye.com/upload/attachment/0104/5680/138b073c-1452-3980-83b6-c177ba5fbf7d.jpg[/img]
3 EJB代码示例
Home接口,位于客户端:
public interface EJBxxxHome extends javax.ejb.EJBHome {
EJBxxxRemote create() throws javax.ejb.CreateException,
java.rmi.RemoteException;
}
Remote接口,位于客户端:
public interface EJBxxxRemote extends javax.ejb.EJBObject {
public String xxxooo(String key)throws Exception, java.rmi.RemoteException;
}
EJB查找代码,位于客户端:
public EJBxxxRemote getxxxEJB(){
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, jndi_factory);// weblogic.jndi.WLInitialContextFactory
props.put(Context.PROVIDER_URL, jndi_url);// t3://localhost:7001
Context ctx = new InitialContext(props);
Object obj = ctx.lookup(jndi_name);// xxx/xxxEJB
EJBxxxHome xxxEJB = (EJBWorkitemHome) PortableRemoteObject
.narrow(obj, EJBWorkitemHome.class);
return xxxEJB.create();
}
Bean实现,位于服务器端:
public class EJBxxxBean implements SessionBean {
public String xxxooo(String key)throws Exception{
return "xxxooo";
}
private SessionContext context;
/**
*
* @ejb.interface-method view-type="both"
*/
public EJBObject getPassedEJBObject() throws EJBException {
try {
return context.getEJBObject();
} catch (Exception ex) {
throw new EJBException("getPassedEJBObject error:",ex);
}
}
public void setSessionContext(SessionContext ctx) throws EJBException {
context = ctx;
}
public void unSetSessionContext() {
context = null;
}
/**
* @ejb:create-method
*/
public void ejbCreate() {
}
/*
* (non-Javadoc)
*
* @see javax.ejb.SessionBean#ejbActivate()
*/
public void ejbActivate() throws EJBException {
}
/*
* (non-Javadoc)
*
* @see javax.ejb.SessionBean#ejbPassivate()
*/
public void ejbPassivate() throws EJBException {
}
/*
* (non-Javadoc)
*
* @see javax.ejb.SessionBean#ejbRemove()
*/
public void ejbRemove() throws EJBException {
}
}
部署描述符,打包到jar的META-INF目录下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd">
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>xxxEJB</ejb-name>
<enable-call-by-reference>true</enable-call-by-reference>
<jndi-name>xxx/xxxEJB</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
其中的jndi-name同查找代码中的变量jndi_name对应。
ejb-name跟下面的配置文件中的ejb-name对应。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar id="xxxEJB-jar">
<description><![CDATA[Workflow EJB DESCRIPITON]]></description>
<display-name>xxx ejb</display-name>
<enterprise-beans>
<!-- Session Beans -->
<session id="xxxEJB-ejb">
<display-name>xxxEJB</display-name>
<ejb-name>xxxEJB</ejb-name>
<home>
EJBxxxHome
</home>
<remote>
EJBxxxRemote
</remote>
<ejb-class>
EJBxxxBean
</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
</session>
</ejb-jar>
然后将这个部署描述文件打包到jar包中,将jar包通过应用服务器发布成EJB服务。
4 EJB的劣势
复杂性:如上节所示,为了编写一个EJB,比如写Home接口,部署描述符、Bean实现等,代码编写复杂,虽然好多只是复制粘贴,但是也容易被吓着,也增加了出错的机率。
侵入性:使用EJB必须使用javax.ejb的接口,这样代码就绑定在EJB上了,而Spring的侵入性小。
ORM:EJB的持久化方案巨难用,饱受诟病,只是听说,笔者并没用过,而Spring取其他框架之所长,可以集成Hibernate,iBATIS等。聪明人啊,做不过你就把你的拿过来用。
调试困难:使用EJB必须要使用EJB容器,这就要求如果要测试,必须先启动应用服务器,然后测试,代码修改后又要重新来过,如果凑巧您机器慢点,那么就只能呵呵了,对不起了,加班吧您。
只讲劣势不讲优势,貌似对EJB有点不公啊,对不起了EJB老大。
Spring是一个开源框架,它是为简化企业级系统开发而生的,由Rod Johnson大师创建。Spring正如其名,使开发者从EJB的繁琐中解脱出来,使企业级开发迎来了春天,感受到春天般的温暖。
1.1 Spring关键词
轻量: 主要从spring大小和处理开支来说的。
非侵入性: 使用spring一般不依赖于spring的类,当然为了使用一些特性,也会依赖于spring的类,但是不像其他框架那样,必须依赖框架的类。
IoC(控制反转):通过IoC实现对象之间的松耦合,对象之间的依赖关系交由spring容器,由spring容器负责将对象依赖的类注入给它。这是spring的核心概念。
AOP(面向切面编程):通过面向切面编程将业务逻辑和系统服务(例如事务,监控,日志等)分离开来,从而让业务逻辑更加简洁清晰。
容器:spring是一个容器,他管理着系统对象的生命周期和配置,配置对象之间的关联关系,但不像EJB容器那样笨重、庞大。
框架:spring是一个框架,它提供了很多基础服务,使用每个框架都会遵守框架的约定,有框架带有的特征。
1.2 Spring模块
[img]http://dl2.iteye.com/upload/attachment/0104/5682/dafc7fd0-8edf-3d49-bd06-ce5c20fbac54.jpg[/img]
--图片截自《spring in action 3rd》,虽然看到好几个版本的模块组成图,但是下面这几个核心的基本都包含。
核心spring容器:容器是spring框架的核心,负责Bean的创建、配置和管理。主要包括BeanFactory和ApplicationContext。
AOP模块:提供了面向切面编程。
数据访问和集成:spring的jdbcTemplate封装了创建连接,释放连接等样板式代码,使jdbc代码更加简洁。另外spring并不想重复发明轮子,他的ORM解决思想是让spring可以集成ORM框架,如Hibernate,iBATIS等。
Web和远程调用:spring提供了MVC框架,另外spring通过RMI,JAX-RPC和WebService提供远程调用代理。
2 Spring vs EJB
由于spring是简化企业级系统开发而生的,那么它必然带有许多企业级服务的支持,所以它被看做了EJB的替代者,但实际上他们二者是可以和平相处的,也可以共存。
spring和EJB功能比较表:
[img]http://dl2.iteye.com/upload/attachment/0104/5680/138b073c-1452-3980-83b6-c177ba5fbf7d.jpg[/img]
3 EJB代码示例
Home接口,位于客户端:
public interface EJBxxxHome extends javax.ejb.EJBHome {
EJBxxxRemote create() throws javax.ejb.CreateException,
java.rmi.RemoteException;
}
Remote接口,位于客户端:
public interface EJBxxxRemote extends javax.ejb.EJBObject {
public String xxxooo(String key)throws Exception, java.rmi.RemoteException;
}
EJB查找代码,位于客户端:
public EJBxxxRemote getxxxEJB(){
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, jndi_factory);// weblogic.jndi.WLInitialContextFactory
props.put(Context.PROVIDER_URL, jndi_url);// t3://localhost:7001
Context ctx = new InitialContext(props);
Object obj = ctx.lookup(jndi_name);// xxx/xxxEJB
EJBxxxHome xxxEJB = (EJBWorkitemHome) PortableRemoteObject
.narrow(obj, EJBWorkitemHome.class);
return xxxEJB.create();
}
Bean实现,位于服务器端:
public class EJBxxxBean implements SessionBean {
public String xxxooo(String key)throws Exception{
return "xxxooo";
}
private SessionContext context;
/**
*
* @ejb.interface-method view-type="both"
*/
public EJBObject getPassedEJBObject() throws EJBException {
try {
return context.getEJBObject();
} catch (Exception ex) {
throw new EJBException("getPassedEJBObject error:",ex);
}
}
public void setSessionContext(SessionContext ctx) throws EJBException {
context = ctx;
}
public void unSetSessionContext() {
context = null;
}
/**
* @ejb:create-method
*/
public void ejbCreate() {
}
/*
* (non-Javadoc)
*
* @see javax.ejb.SessionBean#ejbActivate()
*/
public void ejbActivate() throws EJBException {
}
/*
* (non-Javadoc)
*
* @see javax.ejb.SessionBean#ejbPassivate()
*/
public void ejbPassivate() throws EJBException {
}
/*
* (non-Javadoc)
*
* @see javax.ejb.SessionBean#ejbRemove()
*/
public void ejbRemove() throws EJBException {
}
}
部署描述符,打包到jar的META-INF目录下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd">
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>xxxEJB</ejb-name>
<enable-call-by-reference>true</enable-call-by-reference>
<jndi-name>xxx/xxxEJB</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
其中的jndi-name同查找代码中的变量jndi_name对应。
ejb-name跟下面的配置文件中的ejb-name对应。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar id="xxxEJB-jar">
<description><![CDATA[Workflow EJB DESCRIPITON]]></description>
<display-name>xxx ejb</display-name>
<enterprise-beans>
<!-- Session Beans -->
<session id="xxxEJB-ejb">
<display-name>xxxEJB</display-name>
<ejb-name>xxxEJB</ejb-name>
<home>
EJBxxxHome
</home>
<remote>
EJBxxxRemote
</remote>
<ejb-class>
EJBxxxBean
</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
</session>
</ejb-jar>
然后将这个部署描述文件打包到jar包中,将jar包通过应用服务器发布成EJB服务。
4 EJB的劣势
复杂性:如上节所示,为了编写一个EJB,比如写Home接口,部署描述符、Bean实现等,代码编写复杂,虽然好多只是复制粘贴,但是也容易被吓着,也增加了出错的机率。
侵入性:使用EJB必须使用javax.ejb的接口,这样代码就绑定在EJB上了,而Spring的侵入性小。
ORM:EJB的持久化方案巨难用,饱受诟病,只是听说,笔者并没用过,而Spring取其他框架之所长,可以集成Hibernate,iBATIS等。聪明人啊,做不过你就把你的拿过来用。
调试困难:使用EJB必须要使用EJB容器,这就要求如果要测试,必须先启动应用服务器,然后测试,代码修改后又要重新来过,如果凑巧您机器慢点,那么就只能呵呵了,对不起了,加班吧您。
只讲劣势不讲优势,貌似对EJB有点不公啊,对不起了EJB老大。