beyond_beyond 听着beyond的歌长大了

J2EE VS dotNET

导航

spring1.1简介

2、Application Context
(1)什么是Application Context
 聚集能够被所有组件使用的应用程序信息
 Bean定义的位置
 加载多个contexts
 层次contexts
 il8n,消息资源
 资源访问
 事件传播
(2)ApplicationContext
 扩展BeanFactory
 可以有一个父context
 实现:
 FileSystemXmlApplicationContext
 ClassPathXmlApplicationContext
 XmlWebApplicationContext
 例子:
ApplicationContext ctx = new FileSystemXmlApplicationContext("c:/beans.xml");
ExampleBean eb = (ExampleBean)ctx.getBean("exampleBean");
 ApplicationContext可以读取多个文件
String[] ctxs = new String[]{"ctx1.xml", "ctx2.xml"};
ApplicationContext ctx = new FileSystemXmlApplicationContext(ctxs);
(3)层次contexts
 如果一个Bean在context中没有找到,就会到父context中去找
 创建一个层次contexts
ApplicationContext parent = new ClassPathXmlApplicationContext("ctx1.xml");
ApplicationContext ctx = new FileSystemXmlApplicationContext("ctx2.xml", parent);
(4)资源
 ApplicationContext处理资源位置
 ApplicationContext方法:
Resource getResource(String location)
 URL全路经,如file:c:/test.dat
 相对文件路径,如WEB-INF/test.dat
 classpath伪URL,如classpath:test.dat
interface Resource {
boolean exists();
boolean isOpen();
String getDescription();
File getFile() throws IOException;
InputStream getInputStream() throws IOException;
}
(5)资源编辑器
 内建PropertyEditor
 能够在Bean定义中配置资源属性
 例子:
<property name="resourceProperty">
<value>example/image.gif</value>
</property>
(6)il8n
 国际化应用程序消息
 ApplicationContext方法:
String getMessage(String code, Object[] args, String default, Locale loc)
代表一个messageSource Bean。
 ApplicationContext搜索messageSource Bean(必须实现MessageSource接口)
 例子:在classpath中定义两个资源束messages和errors
<bean id="messageSource" class="...ResourceBundleMessageSource">
<property name="basenames">
<value>messages,errors</value>
</property>
</bean>
在classpath中搜索:
messages_pt_BR.properties errors_pt_BR.properties
messages_pt.properties errors_pt.properties
messages.properties errors.properties
(7)事件
 事件传播
 ApplicationContext处理事件,调用侦听器
 Beans必须实现ApplicationListener接口来接收事件
 应用程序可以扩展ApplicationEvent
 内建事件:
 ContextRefreshedEvent
 ContextClosedEvent
 RequestHandledEvent
 侦听事件
public class MyListenerBean implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent e) {
// process event
}
}
 发送事件
public class ExampleBean implements ApplicationContextAware {
ApplicationContext ctx;
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
public void sendEvent() {
ctx.publishEvent(new MyApplicationEvent(this));
}
}
(8)BeanFactoryPostProcessor
 可以用来在它内部配置BeanFactory或Beans;应用程序contexts在它们的Bean定义中自动检测BeanFactoryPostProcessor的Beans,在其它Beans创建之前应用它们
 post processor bean必须实现BeanFactoryPostProcessor接口
 例子:增加定制编辑器到context中
public class MyPostProcessor implements BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory bf) {
DateFormat fmt = new SimpleDateFormat("d/M/yyyy");
CustomDateEditor dateEditor = new CustomDateEditor(fmt, false);
bf.registerCustomEditor(java.util.Date.class, dateEditor);
}
}

<bean id="myPostProcessor" class="eg.MyPostProcessor"/>
(9)CustomEditorConfigurer
 BeanFactoryPostProcessor实现允许方便的注册定制属性编辑器
<bean id="customEditorConfigurer" class="...CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean class="...CustomDateEditor">
<constructor-arg index="0">
<bean class="java.text.SimpleDateFormat">
<constructor-arg><value>d/M/yyyy</value></constructor-arg>
</bean>
</constructor-arg>
<constructor-arg index="1"><value>false</value></constructor-arg>
</bean>
</entry>
</map>
</property>
</bean>
(10)典型的应用程序contexts
 应用程序contexts通常与J2EE服务器定义的一个范围相联系
 Web应用程序(javax.servlet.ServletContext):Sring提供通过侦听器或Servlet实例化该context的能力
 Servlet:每个Servlet能够拥有自己的应用程序context,来源于Web应用程序context
 EJBs:从EJB jar文件中的XML文档中加载
 不需要使用Singleton来引导Bean Factory

3、AOP
(1)Aspect-oriented Programming
 补充OOP
 分解问题的各个方面(或关系)
 模块化关系
 用法:
 持久化
 事务管理
 安全
 日志管理
 调试
(2)AOP概念
 Aspect:模块化关系(concern)
 Joinpoint:程序执行时的一个点
 Advice:在具体joinpoint做的动作
 Pointcut:一个Advice应该激活的指定joinpoint集合
 Introduction:添加方法或域到Advice类中
(3)Pointcut
 一个Advice应该激活的指定joinpoint集合
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
public interface ClassFilter {
boolean matches(Class clazz);
}
public interface MethodMatcher {
boolean matches(Method m, Class targetClass);
boolean matches(Method m, Class targetClass, Object[] args);
boolean isRuntime();
}
限制pointcut为一组target类;静态pointcuts不需要使用带参数的方法
(4)Pointcut实现
 正则表达式
<bean id="gettersAndSettersPointcut"
class="org.springframework.aop.support.RegexpMethodPointcut">
<property name="patterns">
<list>
<value>.*\.get.*</value>
<value>.*\.set.*</value>
</list>
</property>
</bean>
方法名全路经匹配Perl5正则表达式
(5)Advice
 在具体joinpoint做的动作
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
Spring使用包围joinpoint的拦截器(Interceptor)链来实现Advice
 例子:
public class DebugInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation)
throws Throwable {
System.out.println(">> " + invocation); // before
Object rval = invocation.proceed();
System.out.println("<< Invocation returned"); // after
return rval;
}
}
(6)Advice类型
 Around Advice(如前面的例子)
 Before Advice
 Throws Advice
 After returning Advice
 Introduction Advice
(7)Spring Advisors
 PointcutAdvisor = Pointcut + Advice
 每个内建的Advice都有一个Advisor
 例子:
<bean id="gettersAndSettersAdvisor"
class="...aop.support.RegexpMethodPointcutAroundAdvisor">
<property name="interceptor">
<ref local="interceptorBean"/>
</property>
<property name="patterns">
<list>
<value>.*\.get.*</value>
<value>.*\.set.*</value>
</list>
</property>
</bean>
(8)ProxyFactory
 使用ProxyFactory获得Advised对象
 定义应用的pointcuts和advices
 以代理对象返回interceptor
 使用Java动态代理或CGLIB2(可以代理接口和类)
 编程方式创建AOP代理
ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);
factory.addInterceptor(myMethodInterceptor);
factory.addAdvisor(myAdvisor);
MyBusinessInterface b = (MyBusinessInterface)factory.getProxy();
(9)ProxyFactoryBean
 用来获得Bean的代理
 要代理的Bean:
<bean id="personTarget" class="eg.PersonImpl">
<property name="name"><value>Tony</value></property>
<property name="age"><value>51</value></property>
</bean>
PersonImpl实现Person接口
 Interceptors和Advisors:
<bean id="myAdvisor" class="eg.MyAdvisor">
<property name="someProperty"><value>Something</value></property>
</bean>
<bean id="debugInterceptor" class="...aop.interceptor.NopInterceptor">
</bean>
 代理:
<bean id="person" class="...aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>eg.Person</value></property>
<property name="target"><ref local="personTarget"/></property>
<property name="interceptorNames">
<list>
<value>myAdvisor</value>
<value>debugInterceptor</value>
</list>
</property>
</bean>
 使用Bean:
 客户程序应该获得person Bean,而不是personTarget
 可以通过应用程序context或编程方式来访问
<bean id="personUser" class="com.mycompany.PersonUser">
<property name="person"><ref local="person" /></property>
</bean>

Person person = (Person) factory.getBean("person");
 如果是代理类而不是接口
 将proxyTargetClass设置为true,来替代proxyInterfaces
 代理要扩展target类(由CGLIB来构造)
<bean id="person" class="...aop.framework.ProxyFactoryBean">
<property name="proxyTargetClass"><value>true</value></property>
<property name="target"><ref local="personTarget"/></property>
<property name="interceptorNames">
<list>
<value>myAdvisor</value>
<value>debugInterceptor</value>
</list>
</property>
</bean>
(10)AutoProxy
 自动代理的创建:
 只要定义targets
 选择的Bean会被自动代理
 不需要为每个target Bean使用ProxyFactoryBean
(11)BeanNameAutoProxyCreator
 使用Bean名选择targets
<bean id="employee1" class="eg.Employee">...</bean>
<bean id="employee2" class="eg.Employee">...</bean>
<bean id="myInterceptor" class="eg.DebugInterceptor"/>
<bean id="beanNameProxyCreator"
class="...aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames"><value>employee*</value></property>
<property name="interceptorNames">
<list>
<value>myInterceptor</value>
</list>
</property>
</bean>
(12)AdvisorAutoProxyCreator
 自动应用Advisors到context中的Bean
 每个Advisor对应一个pointcut和advice
 如果pointcut应用到Bean,就会被advice拦截
 有助于保持同一个advice应用到多个事务对象的一致性
 不可能获得没有advised的对象
 例子:
<bean id="debugInterceptor" class="app.DebugInterceptor"/>
<bean id="getterDebugAdvisor"
class="...aop.support.RegexpMethodPointcutAdvisor">
<constructor-arg>
<ref bean="debugInterceptor"/>
</constructor-arg>
<property name="pattern"><value>.*\.get.*</value></property>
</bean>
这个Advisor应用debugInterceptor到任何类的所有get方法
<bean id="autoProxyCreator"
class="...aop.framework.autoproxy.AdvisorAutoProxyCreator">
<property name="proxyTargetClass"><value>true</value></property>
</bean>
(13)AOP高级特性
 元数据驱动的自动代理
 目标源(TargetSources)
 热交换目标源:当允许调用者保持他的引用时,允许切换代理的Bean
 目标源池:维护相同实例的池,在方法激活时释放对象到池中
4、元数据属性
(1)源码级别的元数据
 编程元素的附加属性或注解:通常是类或/和方法
/**
* Normal comments
* @@org.springframework.transaction.interceptor.DefaultTransactionAttribute()
*/
public class PetStoreImpl implements PetStoreFacade, OrderService {
...
}

/**
* Normal comments
* @@org.springframework.transaction.interceptor.RuleBasedTransactionAttribute()
* @@org.springframework.transaction.interceptor.RollbackRuleAttribute(Exception.class)
* @@org.springframework.transaction.interceptor.NoRollbackRuleAttribute("ServletException")
*/
public void echoException(Exception ex) throws Exception {
....
}
 Spring提供元数据的实现:
 使用Jakarta Commons Attributes(创建过程需要一个属性编译步骤)
 JSR-175(JDK 1.5)计划
 用法:
 AOP:属性用来指定Aspects
 最小化Web层配置:到控制器的URL映射
 验证
二、Spring集成
1、Mail
(1)SimpleMailMessage
 创建消息
SimpleMailMessage msg = new SimpleMailMessage();
msg.setFrom("me@mail.org");
msg.setTo("you@mail.org");
msg.setCc(new String[] {"he@mail.org", "she@mail.org"});
msg.setBcc(new String[] {"us@mail.org", "them@mail.org"});
msg.setSubject("my subject");
msg.setText("my text");
(2)MailSender
 定义消息发送者
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host"><value>smtp.mail.org</value></property>
<property name="username"><value>joe</value></property>
<property name="password"><value>abc123</value></property>
</bean>
 发送消息
MailSender sender = (MailSender) ctx.getBean("mailSender");
sender.send(msg);

2、调度(scheduling)
(1)调度程序
 内建支持:
 Java 2 Timer:Timer、TimerTask
 Quartz:Schedulers、JobDetails、Triggers
(2)ScheduledTimerTask
 我们想要运行的任务
public class MyTask extends TimerTask {
public void run() {
// do something
}
}

<bean id="myTask"
class="...scheduling.timer.ScheduledTimerTask">
<property name="timerTask">
<bean class="eg.MyTask"/>
</property>
<property name="delay"><value>60000</value></property>
<property name="period"><value>1000</value></property>
</bean>
包装java.util.TimerTask调度的Bean
(3)TimerFactoryBean
 创建调度器
<bean id="scheduler"
class="...scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list><ref bean="myTask"/></list>
</property>
</bean>
创建一个java.util.Timer对象
 在Bean创建时,Timer开始运行

3、JNDI
(1)JndiTemplate
 使用JndiTemplate
Properties p = new Properties();
p.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
p.setProperty("java.naming.provider.url",
"jnp://localhost:1099");
JndiTemplate jndi = new JndiTemplate(p);
Properties env = jndi.getEnvironment();
try {
jndi.bind("Something", something);
Object o = jndi.lookup("Something");
jndi.unbind("Something");
}
catch(NamingException e) {
...
}
(2)JndiObjectFacroryBean
 使用Bean替代loopup
<bean id="jndiTemplate"
class="org.springframework.jndi.JndiTemplate">
<constructor-arg>
<props>
<prop key="java.naming.factory.initial">
org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.provider.url">jnp://localhost:1099</prop>
</props>
</constructor-arg>
</bean>
<bean id="something"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate"><ref bean="jndiTemplate"/></property>
<property name="jndiName"><value>Something</value></property>
</bean>

Object o = ctx.getBean("something");
4、JDBC
(1)JDBC概要
 使JDBC使用更容易,更少出错
 由框架来处理资源的创建和释放
 由框架来管理异常处理
(2)JdbcTemplate
 执行SQL查询、更新语句和存储过程调用
 循环遍历ResultSet和提取返回的参数值
 例子:
DataSource ds = DataSourceUtils.getDataSourceFromJndi("MyDS");
JdbcTemplate jdbc = new JdbcTemplate(ds);
jdbc.execute("drop table TEMP");
jdbc.update("update EMPLOYEE set FIRSTNME=? where LASTNAME=?",
new String[] {"JOE", "LEE"});
 使用方便方法进行查询
int maxAge = jdbc.queryForInt("select max(AGE) from EMPLOYEE");
String name = (String)jdbc.queryForObject(
"select FIRSTNME from EMPLOYEE where LASTNAME='LEE'", String.class);
List employees = jdbc.queryForList(
"select EMPNO, FIRSTNME, LASTNAME from EMPLOYEE");
返回一个ArrayList(一个条目对应一行)的HashMap(一个条目对应一列,使用列名做key)
 使用回调方法查询
final List employees = new LinkedList();
jdbc.query("select EMPNO, FIRSTNME, LASTNAME from EMPLOYEE",
new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
Employee e = new Employee();
e.setEmpNo(rs.getString(1));
e.setFirstName(rs.getString(2));
e.setLastName(rs.getString(3));
employees.add(e);
}
});
 存储过程
jdbc.call(new CallableStatementCreator() {
public CallableStatement createCallableStatement(Connection conn)
throws SQLException {
return conn.prepareCall("my query");
}
}, params);
 批更新
BatchPreparedStatementSetter setter =
new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i)
throws SQLException {
...
}
public int getBatchSize() {
return ...;
}
};
jdbc.batchUpdate("update ...", setter);
(3)SqlQuery/SqlUpdate对象
 封装查询和更新到Java类中
class EmployeeQuery extends MappingSqlQuery {
public EmployeeQuery(DataSource ds) {
super(ds, "select EMPNO, FIRSTNME, LASTNAME from EMPLOYEE where EMPNO = ?");
declareParameter(new SqlParameter(Types.CHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
Employee e = new Employee();
e.setEmpNo(rs.getString("EMPNO"));
e.setFirstName(rs.getString("FIRSTNME"));
e.setLastName(rs.getString("LASTNAME"));
return e;
}
public Employee findEmployee(String id) {
return (Employee) findObject(id);
}
}
映射结果集的行到一个Java对象
(4)SqlFunction
 封装返回单行的查询
SqlFunction sf = new SqlFunction(dataSource,
"select count(*) from mytable");
sf.compile();
int rows = sf.run();
(5)异常处理
 转换SQLExecption到DataAccessException层面
 通用,更多信息,与DB/JDBC无关(sql错误代码被映射到异常)
 使用RuntimeException(没有检查)
 我们可以覆盖未检查的数据访问异常
try {
// do work
} catch (OptimisticLockingFailureException ex) {
// I'm interested in this
}
(6)数据库连接
 DataSourceUtils:getConnection()、getDatSourceFromJndi()、closeConnectionIfNecessary()
 DriverManagerDataSource
 每次返回一个新的连接
 能够在容器外或测试中使用
 SingleConnectionDataSource
 每次返回同一个连接
 能够在容器外或测试中使用
5、事务管理
(1)事务
 全局事务
 由应用服务器使用JTA管理
 具有同多事务资源工作的能力
 本地事务
 资源规范:如和JDBC连接关联的事务
 不能够在多事务资源之间交叉工作
 不能在全局的JTA事务中运行
 不同的编程模型
(2)Spring解决方案
 对全局和本地事务使用相同的编程模型
 不同的环境采用不同的事务管理策略
 事务管理可以:
 编程方式
 声明方式(如EJB CMT)
(3)事务提取
 事务通过PlatformTransactionManager接口提取
 getTransaction(TransactionDefinition)
 commit(TransactionStatus)
 rollback(TransactionStatus)
 TransactionDefinition:隔离、传播、超时和只读状态
 TransactionStatus
 isNewTransaction()
 setRollbackOnly()
 isRollbackOnly()
(4)事务管理
 内建平台事务管理:
 JtaTransacrionManager
 DataSourceTransacrionManager
 HibernateTransacrionManager
 JdoTransacrionManager
(5)例子
 定义一个JtaTransacrionManager
<bean id="dataSource" class="...jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>MyDS</value></property>
</bean>
<bean id="transactionManager"
class="...transaction.jta.JtaTransactionManager"/>
数据源必须在应用服务器中被配置为事务资源
 定义一个DataSourceTransacrionManager
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
...
</bean>
<bean id="transactionManager"
class="...jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
 定义一个HibernateTransacrionManager
<bean id="sessionFactory"
class="...orm.hibernate.LocalSessionFactoryBean">
...
</bean>
<bean id="transactionManager"
class="...orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
使用JTA来应用Hibernate不需要HibernateTransacrionManager,只要配置JtaTransacrionManager,给出从JNDI获得的sessionFactory数据源
(6)TransactionTemplate
 编程方式的事务管理
 创建一个TransactionTemplate
PlatformTransactionManager transactionManager =
(PlatformTransactionManager) ctx.getBean("myTransactionManager");
TransactionTemplate transaction =
new TransactionTemplate(transactionManager);
 在一个事务中执行
transaction.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus s) {
updateOperation1();
updateOperation2();
}
});
 TransactionTemplate的其它方法
 setPropagationBehavior(int)
 setIsolationLevel(int)
 setReadOnly(Boolean)
 setTimeout(int)
(7)好处
 不同事务管理之间转换
 只是一些配置
 不需要改变代码
 相同的组件可以运行在:
 使用JTA事务的应用服务器
 独立应用程序或Web容器:使用JDBC或开源JTA(如JOTM)
(8)声明式事务
 不需要TransactionTemplate
 使用Spring AOP实现
 类似于EJB CMT:指定事务行为到独立的方法
 和EJB CMT的区别:
 能够应用到任何的POJO
 不需要绑定到JTA(可以和JDBC、JDO和Hibernate一起工作)
 具有声明式rollback规则
 定制事务行为
 不需要支持通过远程调用来传播事务context
(9)TransactionAttributeSource
 定义事务属性如何应用
 TransactionAttributeEditor读取下面形式的定义:
 PROPAGATION_NAME、ISOLATION_NAME、readOnly、+Exception1、-Exception2
 异常名前面的+表示即使异常抛出,也要提交(commit);异常名前面的-表示需要回滚(rollback)
 例子:
 PROPAGATION_MANDATORY、ISOLATION_DEFAULT、-CreateException、-DuplicateKeyException
(10)声明事务
 定义事务拦截器
<bean id="txAttributes"
class="...MatchAlwaysTransactionAttributeSource">
<property name="transactionAttribute">
<value>PROPAGATION_REQUIRED</value>
</property>
</bean>
<bean id="txInterceptor"
class="...transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="myTransactionManager"/>
</property>
<property name="transactionAttributeSource">
<ref bean="txAttributes"/>
</property>
</bean>
MatchAlwaysTransactionAttributeSource应用相同的属性到所有的方法
 可变的TransactionAttributeSource
<bean id="txAttributes"
class="...interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<value>
get*=PROPAGATION_REQUIRED,readOnly
find*=PROPAGATION_REQUIRED,readOnly
load*=PROPAGATION_REQUIRED,readOnly
store*=PROPAGATION_REQUIRED
</value>
</property>
</bean>
NameMatchTransactionAttributeSource应用特定的属性到匹配的方法
 自动代理事务Beans
<bean id="autoProxyCreator"
class="...framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<value>txInterceptor</value>
</property>
<property name="beanNames">
<value>*Dao</value>
</property>
</bean>
 使用元数据属性
<bean id="autoproxy"
class="...aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
</bean>
<bean id="txAdvisor"
class="...transaction.interceptor.TransactionAttributeSourceAdvisor"
autowire="constructor">
</bean>
<bean id="txInterceptor"
class="...transaction.interceptor.TransactionInterceptor"
autowire="byType">
</bean>
<bean id="txAttributeSource"
class="...transaction.interceptor.AttributesTransactionAttributeSource"
autowire="constructor">
</bean>
<bean id="attributes"
class="...metadata.commons.CommonsAttributes">
</bean>
6、ORM
(1)ORM
 ORM:对象关系映射(Object-Relational Mapping)
 内建支持:
 JDO
 iBATIS
 Hibernate
(2)Hibernate配置
 定义DataSource和Hibernate SessionFactory
<bean id="dataSource" ...> ... </bean>
<bean id="sessionFactory" class="...LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>employee.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">....DB2Dialect</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
(3)HibernateTemplate
 创建HibernateTemplate
SessionFactory sessionFactory = (SessionFactory) ctx.getBean("sessionFactory");
HibernateTemplate hibernate = new HibernateTemplate(sessionFactory);
 加载和更新
Employee e = (Employee) hibernate.load(Employee.class, "000330");
e.setFirstName("BOB");
hibernate.update(e);
 使用方便的方法查询
List employees = hibernate.find("from app.Employee");
List list = hibernate.find(
"from app.Employee e where e.lastName=?",
"LEE",
Hibernate.STRING);
List list = hibernate.find(
"from app.Employee e where e.lastName=? and e.firstName=?",
new String[] { "BOB", "LEE" },
new Type[] {Hibernate.STRING , Hibernate.STRING });
 使用回调方法查询
List list = (List) hibernate.execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
List result = session.find("from app.Employee");
// do some further stuff with the result list
return result;
}
});
(4)异常处理
 传递Hibernate异常到DataAccessException层
 采用和JDBC相同的策略
7、EJB
(1)Spring和EJB
 Spring是轻量级容器,在许多场合可以用来替代EJB
 Spring使得访问和实现EJB更容易
(2)EJB访问
 使用EJB通常有:
 服务定位器:关心JNDI、初始化context、EJB Home查找
 业务代表:减少耦合,隐藏实现细节
 使用Spring不需要这些设计模式
(3)访问本地SLSB
 使用本地无状态Session Bean
<bean id="myComponent"
class="...ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName">
<value>myComponent</value>
</property>
<property name="businessInterface">
<value>com.mycom.MyComponent</value>
</property>
</bean>
创建使用服务定位器访问EJB的代理(业务代表)
 你可以交换Bean的实现,而不需要改变客户代码:客户程序使用业务接口,而不是EJB的特定接口
(4)访问远程SLSB
 使用远程无状态Session Bean
<bean id="myComponent"
class="...SimpleRemoteStatelessSessionProxyFactoryBean">
<property name="jndiEnvironment">
<ref bean="myEnvironment"/>
</property>
<property name="jndiName">
<value>myComponent</value>
</property>
<property name="businessInterface">
<value>com.mycom.MyComponent</value>
</property>
</bean>
(5)EJB实现
 AbstractEnterpriseBean
 加载BeanFactory:EJB环境变量ejb/BeanFactoryPath指定XML BeanFactory文件在classpath中的位置;缺省的BeanFactory是XmlApplicationContext
 应用程序只是使用EJB作为前端
 业务逻辑推迟到了BeanFactory的Bean中
(6)实现SLSB
 无状态Session Bean
 扩展AbstractStatelessSessionBean
 保存Session context
 空实现ejbRemove
 ejbCreate()方法
 在ejbActivate()和ejbPassivate()中抛异常
 子类必须实现onEjbCreate()
 例子:
class MySlsb extends AbstractStatelessSessionBean {
protected void onEjbCreate() throws CreateException {
...
}
public void businessMethod() {
BeanFactory bf = getBeanFactory();
MyBusinessBean mbb = bf.getBean("myBusinessBean");
...
}
}
(7)实现SFSB
 保持状态Session Bean
 扩展AbstractStatefulSessionBean
 保存Session context
 空实现ejbRemove
 ejbCreate()方法
 子类必须实现ejbCreate()、ejbActivate()和ejbPassivate()
 例子:
class MySfsb extends AbstractStatefulSessionBean {
public void ejbCreate() throws CreateException {
loadBeanFactory();
...
}
public void ejbActivate() {
...
}
public void ejbPassivate() {
...
}
public void businessMethod() {
BeanFactory bf = getBeanFactory();
MyBusinessBean mbb = bf.getBean("myBusinessBean");
...
}
}
(8)实现MDB
 例子:
class MyMdb extends AbstractJmsMessageDrivenBean {
protected void onEjbCreate() throws CreateException {
...
}
public void onMessage(Message message) {
BeanFactory bf = getBeanFactory();
MyBusinessBean mbb = bf.getBean("myBusinessBean");
...
}
}
8、Web
(1)WebApplicationContext
 应用程序context位于war文件中
 每个应用程序具有单一的根context
 缺省是:/WEB-INF/applicationContext.xml
 context被下面加载:
 ContextLoaderListener(Servlet2.4)
 ContextLoaderServlet(Servlet2.3)
 可以使用任何的Web框架,Spring只是作为一个类库
 例子:
 web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>...web.context.ContextLoaderListener</listener-class>
</listener>
 在servlet中
WebApplicationContextUtils.getWebApplicationContext(ServletContext);

9、Web MVC
 参考《Developoing a Sring Framework MVC application step-by-step》(即将翻译)

10、远程访问(Remoting)
(1)RemoteExporter
 context中的任何Bean多可以被输出
 RemoteExporter以远程服务的方式输出Bean
 内建支持:
 RMI
 JAX-RPC
 Burlap
 Hessian
(2)RmiServiceExporter
 要被输出的服务
class MyServiceImpl implements MyService {
...
}
<bean id="myService" class="app.MyServiceImpl"/>
 服务输出者
<bean id="myService-rmi"
class="...remoting.rmi.RmiServiceExporter">
<property name="service"><ref local="myService"/></property>
<property name="serviceInterface">
<value>app.MyService</value>
</property>
<property name="serviceName">
<value>myService</value>
</property>
</bean>

11、更多
(1)线路图
 Spring1.1
 支持JMS
 支持JMX
 基于规则的声明式验证
 AOP pointcut 表达式语言,JSR175 preview
 Spring1.2
 支持OGNL
 支持JCA
 增强RML支持
 Spring1.3 ?
 JSF
 Portlets
(2)相关的项目
 胖客户平台(sandbox):Spring RCP
 验证(sandbox):通用验证;基于属性
 安全:Acegi Security System for Spring

(译者:2004年7月28日,Spring Framework 1.1 RC1发布,与1.0相比,主要增加了AspectJ集成、JMS支持、远程访问和Web服务支持的增强,具体内容可以参考附带文档中的spring-reference.pdf)

posted on 2005-01-07 15:46  beyond_beyond  阅读(1640)  评论(0)    收藏  举报