AOP的相关术语:
1.通知(Advice):
通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。
2.连接点(Joinpoint):
程序能够应用通知的一个“时机”,这些“时机”就是连接点,例如方法被调用时、异常被抛出时等等。
3.切入点(Pointcut)
通知定义了切面要发生的“故事”和时间,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称,Spring中允许我们方便的用正则表达式来指定
4.切面(Aspect)
通知和切入点共同组成了切面:时间、地点和要发生的“故事”
5.引入(Introduction)
引入允许我们向现有的类添加新的方法和属性(Spring提供了一个方法注入的功能)
6.目标(Target)
即被通知的对象,如果没有AOP,那么它的逻辑将要交叉别的事务逻辑,有了AOP之后它可以只关注自己要做的事(AOP让他做爱做的事)
7.代理(proxy)
应用通知的对象,详细内容参见设计模式里面的代理模式
8.织入(Weaving)
把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:
(1)编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才可以做的到,例如AspectJ的织入编译器
(2)类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码
(3)运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理应该是使用了JDK的动态代理技术
Spring提供了4种实现AOP的方式:
1.经典的基于代理的AOP
2.@AspectJ注解驱动的切面
3.纯POJO切面
4.注入式AspectJ切面
基于代理的AOP:
Spring支持五种类型的通知:
Before(前) org.apringframework.aop.MethodBeforeAdvice
After-returning(返回后) org.springframework.aop.AfterReturningAdvice
After-throwing(抛出后) org.springframework.aop.ThrowsAdvice
Arround(周围) org.aopaliance.intercept.MethodInterceptor
Introduction(引入) org.springframework.aop.IntroductionInterceptor
值的说明的是周围通知,他是由AOP Alliance中的接口定义的而非Spring,周围通知相当于前通知、返回后通知、抛出后通知的结合
这么几个步骤:
1.创建通知:实现这几个接口,把其中的方法实现了
2.定义切点和通知者:在Spring配制文件中配置这些信息
3.使用ProxyFactoryBean来生成代理
具体做法。。。大晚上的就举个睡觉的例子吧:
- 抵触所有的文档,因为“敏捷不需要文档”,也不需要需求文档。
- 2周的冲刺(Sprint)完成了,只是在所有人强制把6周努力“塞到”这2周里面的情况下完成的。
- 用户故事描述的细节比一条微博还要简短,史诗级的(低优先级,更大块的)用户故事描述的是项目大多数的悲剧地方(Epic describes the proportions of most project catastrophes)【译者注,后半句不太明白】。
- 要么没有回顾会议,要么没有采取任何行动,要么行动没有分配到具体负责人那里。
- 功能演示或用户验收测试完全取代了标准测试(如单元测试,系统测试,集成测试或性能测试)。
- 最终用户被迫接受不达标的功能特性和忍受使用中的大量问题,并接受功能将会改进优化的承诺。
- 你的敏捷教练并没有进行指导。
- 燃尽图成了一个真正的燃尽图(The burn down chart is really a burn out chart)【译者注,应该是想表达没有关注曲线数据的含义】。
- 你试图组建一个分布在大企业中或者跨地域的虚拟敏捷团队。
- “完成”的定义跟日期,版本构建,部署或者除可工作的软件以外的任何其他机制相关。
- 自组织团队退化,恶徒把他们的意愿强加到其余团队成员上。(Self Directed Teams have degraded into bands of thugs imposing their wills upon the rest of the team.)
- 你试图重新定义,测试实际是什么,如声明单元测试和系统测试对应的活动。
- 你企业的PMO和资金(关卡)(Your Enterprise PMO and Funding (Tollgate))模型非常适应瀑布模式项目,但你强迫他们去适应到敏捷。
- “团队”不愿意做在他们职位的“工作描述”之外的事情(例如:开发人员测试,测试人员开发)。
- 你看到积极的行为和产出,并认为都是你的敏捷实践的直接结果,然而忽视所有不好的行为和产出,并认为都是个人的问题。
工作的软件 高于 详尽的文档
客户合作 高于 合同谈判
响应变化 高于 遵循计划
- 敏捷是一种没有相关技术的运动。
- 敏捷运动转移松散的、跨部门的软件工程方法到单一专注于软件开发的团队(排除QA和运维)[The Agile movement shifts the broad, inter-departmental process of software engineering to one that is focused on software development to the exclusion of QA and operations.]。
- 敏捷运动通过源代码的频繁变更,把需求的所有权从业务转移到开发[The Agile movement transfers business ownership of requirements to development ownership of requirements through frequent source code changes.]。
- 敏捷实践,致力于更少更快的工作,以便得到持续前进的反馈。
- 敏捷宣言里没有的,却又和它的原则相关的几个词:质量保证,测试,运维。
- 敏捷是一个以开发人员为中心的运动。
- 28%的敏捷践行宣布他们是成功的。
- 19%的报告表示冲刺(Sprint)如预期一样,在制定的时间内完成了所有工作。
- 44%的报告表明他们并不知道什么是返工等级。
- 67%的缺陷是在产品发布后的第4个冲刺里被修复的。
- 59%的敏捷项目里商务人员没有适当参与到其中。
<input onkeyup="value=value.replace(/[\W]/g,'') "
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
ID="Text1" NAME="Text1">
2.只能输入数字的:
<input onkeyup="value=value.replace(/[^\d]/g,'') "
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
ID="Text2" NAME="Text2">
3.只能输入全角的:
<input onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"
ID="Text3" NAME="Text3">
4.只能输入汉字的:
<input onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"
ID="Text4" NAME="Text4">
5.邮件地址验证:
var regu =
"^(([0-9a-zA-Z]+)|([0-9a-zA-Z]+[_.0-9a-zA-Z-]*[0-9a-zA-Z]+))@([a-zA-Z0-9-]+[.])+([a-zA-Z]{2}|net|NET|com|COM|gov|GOV|mil|MIL|org|ORG|edu|EDU|int|INT)$"
var re = new RegExp(regu);
if (s.search(re) != -1) {
return true;
} else {
window.alert ("请输入有效合法的E-mail地址 !")
return false;
}
6.身份证:
"^\\d{17}(\\d|x)$"
7.17种正则表达式
"^\\d+$" //非负整数(正整数 + 0)
"^[0-9]*[1-9][0-9]*$" //正整数
"^((-\\d+)|(0+))$" //非正整数(负整数 + 0)
"^-[0-9]*[1-9][0-9]*$" //负整数
"^-?\\d+$" //整数
"^\\d+(\\.\\d+)?$" //非负浮点数(正浮点数 + 0)
"^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$" //正浮点数
"^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$" //非正浮点数(负浮点数 + 0)
"^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$" //负浮点数
"^(-?\\d+)(\\.\\d+)?$" //浮点数
"^[A-Za-z]+$" //由26个英文字母组成的字符串
"^[A-Z]+$" //由26个英文字母的大写组成的字符串
"^[a-z]+$" //由26个英文字母的小写组成的字符串
"^[A-Za-z0-9]+$" //由数字和26个英文字母组成的字符串
"^\\w+$" //由数字、26个英文字母或者下划线组成的字符串
"^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$" //email地址
"^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$" //url
=============================================
1.取消按钮按下时的虚线框
在input里添加属性值 hideFocus 或者 HideFocus=true
2.只读文本框内容
在input里添加属性值 readonly
3.防止退后清空的TEXT文档(可把style内容做做为类引用)
<INPUT style=behavior:url(#default#savehistory); type=text
id=oPersistInput>
4.ENTER键可以让光标移到下一个输入框
<input onkeydown="if(event.keyCode==13)event.keyCode=9" >
5.只能为中文(有闪动)
<input onkeyup="value="/value.replace(/[" -~]/g,’’)"
onkeydown="if(event.keyCode==13)event.keyCode=9">
6.只能为数字(有闪动)
<input onkeyup="value="/value.replace(/["^\d]/g,’’)
"onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^\d]/g,’’))">
7.只能为数字(无闪动)
<input ime-mode:disabled"
onkeydown="if(event.keyCode==13)event.keyCode=9" onKeypress="if
((event.keyCode<48 || event.keyCode>57)) event.returnValue=false">
8.只能输入英文和数字(有闪动)
<input onkeyup="value="/value.replace(/[\W]/g,"’’)"
onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^\d]/g,’’))">
9.屏蔽输入法
<input type="text" name="url" ime-mode:disabled"
onkeydown="if(event.keyCode==13)event.keyCode=9">
10. 只能输入 数字,小数点,减号(-) 字符(无闪动)
<input onKeyPress="if (event.keyCode!=46 && event.keyCode!=45 &&
(event.keyCode<48 || event.keyCode>57)) event.returnValue=false">
11. 只能输入两位小数,三位小数(有闪动)
<input maxlength=9
onkeyup="if(value.match(/^\d{3}$/))value="/value.replace(value,parseInt(value/10))"
;value="/value.replace(/\.\d*\./g,’."’)" onKeyPress="if((event.keyCode<48
|| event.keyCode>57) && event.keyCode!=46 && event.keyCode!=45 ||
value.match(/^\d{3}$/) || /\.\d{3}$/.test(value))
{event.returnValue=false}" id=text_kfxe name=text_kfxe>