Spring Aop StepByStep.docx
- 文档编号:10030370
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:47
- 大小:49.18KB
Spring Aop StepByStep.docx
《Spring Aop StepByStep.docx》由会员分享,可在线阅读,更多相关《Spring Aop StepByStep.docx(47页珍藏版)》请在冰豆网上搜索。
SpringAopStepByStep
阅读要求:
掌握关于Spring方面的东西。
所以花了两个星期的时间来学习Spring的基本知识,主要包括Ioc和Aop两方面。
本文为笔者的Spring在Aop方面的学习笔记,主要结合了SpringInAction第三章和Spring-Reference第五章为学习向导。
根据自己的理解和书中的实例来一步一步完成对于在Spring中Aop方面的编程。
其中基础部分Ioc需要读者自己参考资料了解,本文将不做描述。
说明:
我将尽量缩短程序长度,在程序部分将减少注释说明,重点要读者自己根据上下文和程序结果理解体会,具体api信息请读者自己参考Spring-api文档和相关资料。
一. 准备工作:
1. 开发环境:
l 适合人群:
要了解SpringIoc,对Spring-Aop可以不了解或者仅仅熟悉Aop概念,未参与SpringAop开发实战的初学者。
同时也希望高手对于本文的不足或理解错误之处给予指点,谢谢。
l 开发环境:
JDK1.4_2
l 开发工具:
Eclipse3.12(未采用任何插件,主要是为初学者熟悉和理解xml文档的配置)
l 所需组件:
Spring-Framework-1.2.8
下载地址
2. 建立工程:
首先用Eclpse建立一个普通java项目,导入jar文件到编译环境中,如下:
a) Spring.jar为Spring的核心jar文件,必须;
b) Commons-loggin.jar日志文件,必须;
c) Cglib.jar动态代理文件,不是必须(本文需要);
d) Jak-oro.jar使用Perl和Awk正则表达式进行文本解析工具,不是必须(本文需要);
建立工程如下:
好了,下来我们开始我们的Spring-aop之旅;
二. Spring-Aop入门
AOP全名Aspect-orientedprogramming。
Springframework是很有前途的AOP技术。
作为一种非侵略性的,轻型的AOPframework,你无需使用预编译器或其他的元标签,便可以在Java程序中使用它。
这意味着开发团队里只需一人要对付AOPframework,其他人还是像往常一样编程。
关键性概念:
1) Advice是代码的具体实现,例如一个实现日志记录的代码。
2) Pointcut是在将Advice插入到程序的条件。
3) advisor是把pointcut和advice的组合在一起装配器。
图例:
你的程序可能如上,现在要在三个流程上同时加入日志控制和权限控制,如下:
你的程序可能如上,现在要在三个流程上同时加入日志控制和权限控制,如下:
其中拿日志为例,日志控制和流程之间的穿插点处叫做连接点(Joinpoint),而Advice就是我们日志处理的具体代码,Pointcut就是定义一个规则,对三个和业务有关的连接点进行过滤和匹配(例如我们对于业务1不做日志处理)。
Advisor就是将符合的规则的剩下的两个连接点和具体的日志记录代码组合在一起。
三. Spring-Aop前置通知、后置通知、环绕通知、异常通知实现
我以SpringInAction提供的例子进行二次改造,完成我们自己的流程。
业务流程很简单,顾客到商店买东西,店员根据顾客的需要给于顾客提供服务。
实现方法前插入,方法后插入,环绕,异常四种。
代码:
建立一个用户类;
publicclassCustomer {
privateStringname="悠~游!
";
publicStringgetName(){
returnname;
}
}
三个产品
publicclassCheese{
publicStringtoString(){
return"奶酪!
";
}
}
publicclassPepper{
publicStringtoString(){
return"胡椒粉!
";
}
}
publicclassSquish{
publicStringtoString(){
return"果酱!
";
}
}
建立一个接口;
publicinterfaceKwikEMart{
SquishbuySquish(Customercustomer)throwsKwikEMartException;
PepperbuyPepper(Customercustomer)throwsKwikEMartException;
CheesebuyCheese(Customercustomer)throwsKwikEMartException;
}
实现这个接口,我们实现三个方法,买奶酪,买胡椒粉,买果酱;
publicclassApuKwikEMartimplementsKwikEMart{
privatebooleancheeseIsEmpty=false;
privatebooleanpepperIsEmpty=false;
privatebooleansquishIsEmpty=false;
publicCheesebuyCheese(Customercustomer)throwsNoMoreCheeseException{
if(cheeseIsEmpty){
thrownewNoMoreCheeseException();
}
Cheeses=newCheese();
System.out.println("--我想买:
"+s);
returns;
}
publicPepperbuyPepper(Customercustomer)throwsNoMorePepperException{
if(pepperIsEmpty){
thrownewNoMorePepperException();
}
Peppers=newPepper();
System.out.println("--我想买:
"+s);
returns;
}
publicSquishbuySquish(Customercustomer)throwsNoMoreSquishException{
if(squishIsEmpty){
thrownewNoMoreSquishException();
}
Squishs=newSquish();
System.out.println("--我想买:
"+s);
returns;
}
publicvoidsetCheeseIsEmpty(booleancheeseIsEmpty){
this.cheeseIsEmpty=cheeseIsEmpty;
}
publicvoidsetPepperIsEmpty(booleanpepperIsEmpty){
this.pepperIsEmpty=pepperIsEmpty;
}
publicvoidsetSquishIsEmpty(booleansquishIsEmpty){
this.squishIsEmpty=squishIsEmpty;
}
}
环绕通知的实现,必须实现invoke方法,通过调用invoke.proceed()手工调用对象方法:
publicclassOnePerCustomerInterceptorimplementsMethodInterceptor{
privateSetcustomers=newHashSet();
publicObjectinvoke(MethodInvocationinvoke)throwsThrowable{
Customercustomer=(Customer)invoke.getArguments()[0];
if(customers.contains(customer)){
thrownewKwikEMartException("Onepercustomer.");
}
System.out.println("店员:
"+customer.getName()+",CanIhelpyou?
");
Objectsquishee=invoke.proceed();//手工调用对象方法;
System.out.println("店员:
OK!
"+customer.getName()+".giveyou!
");
customers.add(squishee);
returnsquishee;
}
}
前置通知的实现
publicclassWelcomeAdviceimplementsMethodBeforeAdvice{
publicvoidbefore(Methodmethod,Object[]args,Objecttarget)throwsThrowable{
Customercustomer=(Customer)args[0];
System.out.println("店员:
:
Hello"+customer.getName()+".Howareyoudoing?
");
}
}
publicclassCustomer {
privateStringname="悠~游!
";
publicStringgetName(){
returnname;
}
}
后置通知实现;
publicclassThankYouAdviceimplementsAfterReturningAdvice{
publicvoidafterReturning(ObjectreturnValue,Methodmethod,Object[]args,Objecttarget)throwsThrowable{
Customercustomer=(Customer)args[0];
System.out.println("店员:
Thankyou"+customer.getName()+".Comeagain!
");
}
}
系统异常处理通知实现;
publicclassKwikEmartExceptionAdviceimplementsThrowsAdvice{
publicvoidafterThrowing(NoMoreSquishExceptione){
System.out.println("系统:
NoMoreSquisheesException异常截获了:
"+e.getMessage());
}
publicvoidafterThrowing(NoMoreCheeseExceptione){
System.out.println("系统:
NoMoreCheeseException异常截获了:
"+e.getMessage());
}
publicvoidafterThrowing(NoMorePepperExceptione){
System.out.println("系统:
NoMorePepperException异常截获了:
"+e.getMessage());
}
}
自定义的异常接口;
publicclassKwikEMartExceptionextendsException{
privatestaticfinallongserialVersionUID=-3962577696326432053L;
StringretValue="KwikEMartException异常!
";
publicKwikEMartException(Stringname){
retValue=name;
}
publicKwikEMartException(){
}
publicStringgetMessage(){
returnretValue;
}
}
没有更多的奶酪异常;
publicclassNoMoreCheeseExceptionextendsKwikEMartException{
privatestaticfinallongserialVersionUID=-3961123496322432053L;
StringretValue="NoMoreCheeseException异常!
";
publicNoMoreCheeseException(){
super();
}
publicNoMoreCheeseException(Stringname){
super(name);
}
publicStringgetMessage(){
returnretValue;
}
}
没有更多的胡椒粉异常;
publicclassNoMorePepperExceptionextendsKwikEMartException{
privatestaticfinallongserialVersionUID=-3961234696322432053L;
StringretValue="NoMorePepperException异常!
";
publicNoMorePepperException(){
super();
}
publicNoMorePepperException(Stringname){
super(name);
}
publicStringgetMessage(){
returnretValue;
}
}
没有更多的果酱异常;
publicclassNoMoreSquishExceptionextendsKwikEMartException{
privatestaticfinallongserialVersionUID=-3121234696322432053L;
StringretValue="NoMoreSquishException异常!
";
publicNoMoreSquishException(){
super();
}
publicNoMoreSquishException(Stringname){
super(name);
}
publicStringgetMessage(){
returnretValue;
}
}
运行实例类;
publicclassRunDemo{
publicstaticvoidkwikEMart(){
ClassPathXmlApplicationContextcontext=newClassPathXmlApplicationContext("demo/kwikemart.xml");
//如果你想通过类来引用这个的话,就要用到CGLIB.jar了,同时在代理工厂里面设置:
//
KwikEMartakem=(KwikEMart)context.getBean("kwikEMart");
try{
akem.buySquish(newCustomer());
akem.buyPepper(newCustomer());
akem.buyCheese(newCustomer());
}catch(KwikEMartExceptione){
//异常已经被截获了,不信你看控制台!
~;
}
}
publicstaticvoidmain(String[]args){
kwikEMart();
}
}
Xml文件配置:
xmlversion="1.0"encoding="UTF-8"?
>
DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http:
//www.springframework.org/dtd/spring-beans.dtd">
--
把这里注释去掉的话,程序调用的时候测试异常通知;
-->
--方法调用前通知 -->
--方法调用后通知-->
--环绕调用通知 -->
--异常调用通知 -->
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Spring Aop StepByStep