放到这里留作备份.还有一个pdf版的更详细.
发现用spring有一个问题,如果某个人忘记加入一个类文件,而这个依赖是在spring中体现的,那么在编译时不会报错, 而显然是不好的.这种错误应该在编译的时候就应该报出来. 考虑在编译时检查一次bean依赖, 最简单就是初始化一次application-context.
今天在整合acegi和struts-menu的时候老是有问题,跟进源代码发现struts-menu的RolesPermissionsAdapter 中:
public boolean isAllowed(MenuComponent menu) {
if (menu.getRoles() == null) {
return true; // no roles define, allow everyone
} else {
// Get the list of roles this menu allows
String[] allowedRoles = delimiters.split(menu.getRoles());
for (int i=0; i < allowedRoles.length; i++) {
if (request.isUserInRole(allowedRoles[i])) {
return true;
}
}
}
return false;
}
request.isUserInRole(allowedRoles[i])返回是false. - 因为这个request是sitemesh的pageinforequestWrapper!!!
(之前找了各种可能都没有发现异常,试了无数种 可能的原因)
为什么会这样,之前做的也是完全一样啊?仔细比较了以前写的和现在的,发现 filter-mapping的顺序不一样:
之前写的是acegi的filter-mapping在第一个,试着把现在的filtermapping 放到第一个.成功!
原来filter-mapping的顺序也是有讲究的.如果先mapping sitemesh的filter,request就会被sitemesh的pageinforequestwrapper(?) 包裹,然后就不能被acegi的filter包装成SecurityContextHolderAwareRequestWrapper.
这样在调用isUserInRole时候就出问题了,因为使用的不是acegi的实现.
记录下来.
用springide验证了一下xml文件,得到这个错误
Destroy-method ’shutdown’ not found in bean class ‘org.enhydra.jdbc.pool.StandardXAPoolDataSource’
bean的配置如下:
也就是说springide认为这个bean没有shutdown的方法.查了一下xapool的source,发现是有的,但是是shutdown(boolean).destroy-method属性的定义:
Attribute : destroy-method
The name of the custom destroy method to invoke on bean factory shutdown. The method must
have no arguments, but may throw any exception. Note: Only invoked on beans whose lifecycle is
under the full control of the factory - which is always the case for singletons, […]
刚刚“领略”了一些spring-modules的源代码看到了FactoryBean和InitiliazingBean的用处。记在这里
InitializingBean.afterPropertiesSet()
这个方法比较容易理解,是在spring根据配置文件设置了bean的属性后调用的,一般这里会做一些初始化的工作。比如,xml配置中只是提供了resource的路径,在这个方法里 就要根据resource的路径初始化一些成员变量(那些不能被注入或者没有被注入的成员变量)。
public void afterPropertiesSet() throws Exception {
if (this.definitionLocation == null) {
throw new FatalBeanException(”Property [definitionLocation] of class [”
+ ProcessDefinitionFactoryBean.class.getName()
+ “] is required.”);
}
InputStream inputStream = null;
try {
inputStream = this.definitionLocation.getInputStream();
this.processDefinition = ProcessDefinition.parseXmlInputStream(inputStream);
// 这里就是初始化的地方,spring的配置文件中只配置了definitionLocation的信息,其他的事就在这里做
}
finally {
if (inputStream != null) {
inputStream.close();
}
}
}
FactoryBean.getObject & getObjectType
在比较配置文件和源代码的时候我很疑惑,为什么类型都不对头,怎么可以注入的?答案就在FactoryBean的这两个方法里
public Object getObject() throws Exception {
return this.processDefinition;
}
public Class getObjectType() {
return (processDefinition == null) ? ProcessDefinition.class : […]
如果IOC是运行时对象依赖关系的注入的话,那么AOP是不是就是运行期执行流的注入呢?
每个注入点(point cut)就对应IOC中的sette或构造函数参数.每个处理方法(advice)就对应IOC中的一个对象
(最初发布在JavaResearch.org,现在整理好放到自己的地方.)
有人说spring aop+ spring ioc, 才~~~是spring
简单一点,是一个容器. 什么容器,容纳什么?是对象,或者说bean的容器.
那为什么叫轻量级容器呢?相对于EJB container,使用spring不需要写符合容器规范的代码,即容器不会”侵入”了你的代码.
这 个容器会提供你的应用(程序)中用到的所有对象,并对这些对象进行统一的生命周期管理和组装.在通常的开发中,我们在需要某个对象的时候只是 new MyObject(). 在Java中,这样没有什么不好,因为gc会打理好”善后”工作,是系统级的. 而用spring,在需要某个对象 时,只要向容器请求相应的对象,spring会找到并准备好这些对象并提供给你.她也会打理好”善后”工作,但是是在应用级的.
另一方面,spring还会帮助你打理对象之间的依赖关系.
比如原来的做法:
class A{
}
class B{
A a ;
public B(){ a = new A();}
}
而使用spring的做法
class A{
}
class B{
A a;
public B(){}
void setA(A a){this.a=a}
A getA(){return this.a}
}
(希望你不要单纯地认为spring会写很多代码)
但 从前一个方面,你可能觉得spring只是一个对象容器.从这里你就应该看出,spring是bean容器,因为spring需要你的类符合bean规 范:相应于每一个成员域,都需要提供setter和getter方法.spring要使用这些方法来注入依赖关系,也就是 dependence injection, 或者inversion of control. 我个人觉得还是di更容易理解,直到现在我还是要考虑 怎么去向别人很好的解释ioc.控制反转(倒转),我的理解是就如同上面的两个例子里看到的,依赖(控制)不在体现在代码逻辑里(如第一个例子),而是在 配置文件里,而在代码中我们只提供注入点(也就是setter和getter).
希望我对IoC的概念的讲解能够给你一些启发.
你 可能要问了,为什么我要这样做呢?原来的做法有什么不妥的地方么?没有什么不妥,只是两种理念而已,没有绝对的好还是不好,但我还是给你我的解释–我理 解的IoC的好处,希望有所帮助.通常在程序设计的时候,我们在需要某些功能时,会相应的去设计一些方法,然后根据OO去将方法和一成员变量组成一个类. 实际上,我们最终设计出的程序是:一组类的实例互相交互完成某个特定的任务.
除了一些核心的业务方法,以外我们还要做组装对象的工作.比如我有了 一个工厂,里面有很多机器,机器在开动时要装配相应的模具.那么在工厂的生产过程中, 首先我要有工厂,机器,模具这样三个类.然后我的”动作”有:装 配,开机.通常的做法我们要做装配,然后再去开机.而用spring,我们只是专注于开机.这样我们就把装配这个动作抽离出了核心的”生产过程”.当某些 机器改变了装配模具时,不在需要修改核心业务代码.这就是解耦.如:
public class Production{
public static void main(String[] args){
Factory […]
作者:Edmon Begoli May 5, 2005
翻译:ZhangV 2005-07-22
原文出自:DevX.com
原文链接:http://www.devx.com/webdev/Article/28041/0/page/1
Spring WebFlow是一个全新的Web框架,她带给我们一种全新且高度结构化的Web应用构建方法.让我们来看看她的一些特性.
Spring框架正准备推出一种新的技术.在下一个版本中(1.3,预计在2005年夏天发布)Spring将正式将Spring WebFlow整合进来.Spring WebFlow是一个及其优秀的Web开发框架,用于在Web应用内部创建和配置可重用的Web流程.
熟悉Spring的人可能先入为主地以为Spring WeFlow和SpringMVC没有什么区别.那就错了.Spring MVC是一个轻量级的Web开发框架,而Spring WebFlow 则提出一种全新的视角.她使得Web架构师们可以将精力集中在Web应用开发的抽象层次上:Web流程的逻辑结构和Web事件条件的定义.此外,她还提出许多新的概念.(稍后会介绍到)
本文将回顾这一个新框架前的一些关键概念,用一个经典的用户登录例子来分析流程标记语言的主要组成元素并向您解释为什么WebFlow如此诱人.(读者必需要有Spring 1.2基础).
Spring WebFlow 概念和组件
作为一个Web框架,WebFlow无论在理论上还是在实际开发上都有诸多优点.深厚的软件工程学架构保证了他的稳定性,同时,其组件合理,易于理解,易于使用.
事实上,它更适合中大型应用的开发,因为它的组件模型专门针对架构重用,高效管理性和可配置性进行了优化.
用例研究
本文以一个常见的web应用流程作为示例, 一个身份认证流程,讲解它的一些代码片断.一个Web认证的全过程包括:登录表单,注册表单,认证action,注册action,以及对这些action的结构修饰.这个例子用来展示那些修饰登录表单的组件的配置.
自动操作架构
Spring WebFlow以有限状态机(Finite State machine)的概念为基础.Web应用内部的用户交互行为和事务被建模为一般的状态机,这是一种非常流行的软件工程建模方法.(见图1).自动机为基础的设计是一种很好的设计方法,同时正在越来越收到应用架构的青睐 — 因为它在对Web交互行为建模时显得相对清晰且严谨.
WebFlow的核心组件
一个Spring WebFlow应用中包含一个或多个流程,通常每个流程包括执行Action的动作状态(ActionStates),显示状态(ViewStates),跳转动作(Transitions).
流程
一个流程是一个预先定义好的用户交互行为的集合,表示为一个由动作状态和显示状态构成的树,状态之间通过跳转联系.
下面的登录注册是一个webflow的例子,包含了一些典型的构件,例如loginForm,ActionState,transition.这些构件通过一个XML文件描述:
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE webflow PUBLIC “-//SPRING//DTD WEBFLOW//EN”
“http://www.springframework.org/dtd/spring-webflow.dtd”>
<webflow id=”LoginSequence” start-state=”loginForm”>
<action-state id=”loginForm”>
<action bean=”loginFormAction”/>
<transition on=”success” to=”formView”/>
</action-state>
…
<view-state id=”formView” view=”enterCredentials”>
<transition on=”submit” to=”bindAndValidateForm”/>
</view-state>
…
<end-state id=”successView” view=”displayMain”/>
这个流程以loginForm开始,以”successView”结束(修饰主页面”displayMain” 的组件.流程可以通过XML文档配置,或者AbstractFlowBuilder的子类.
动作状态(ActionStates)
ActionStates对用户事件或其他事件进行响应.ActionStates自身又可以包含其他可执行的Action和transition.下面的代码配置了”loginForm”这个ActionState.
<action-state id=”loginForm”>
<action bean=”loginFormAction”/>
<transition on=”success” to=”formView”/>
</action-state>
动作(Actions)
Action是ActionState可以连接,重用,声明调用的最小单位.Action继承自AbstractAction类,该类实现了doExecuteAction方法.这个方法的参数:RequestContext,WebFlow(其中封装了所有流程相关的数据).loginForm动作状态通过Spring的自动装配特性调用LoginFormAction动作.doExecute
Action方法被自动调用,同时可以处理一些登录准备,预先装入等操作.
public LoginFormAction extends AbstractAction{
protected Event doExecuteAction(RequestContext context)
throws Exception{
//perform some […]