spring基础学习四(aop)
2011-12-05 10:26
453 查看
这里先占个位置,今天晚上下班后完成!
痛苦啊!我们被困在办公室里了!一开门就走吧。只是可惜今天没有写这篇文章了!唉,计划不如变化快啊!
还没写这篇文章呢?就要催着走!
今天补上这一篇的内容:
目录:
1、AOP的原理
2、AOP的使用
1、AOP原理:
AOP编程是面向对象思维方式的有力补充。
面向切面编程就是在要运行的代码 前、后 加一些信息代码,而不影响原来的代码。
如果在框架中,没有AOP的这部分框架,我们自己也可以是实现面向切面编程----有两种比较好的方式:继承方式和组合设计模式
在这段代码前后加代码的话,可以继承这个类,调用super的方式:
但是如过想在这段代码前后在加内容就要再继承它:
问题来了,你如过想让RunTime在前,Log再后,那改代码就很麻烦了。需要让Algorithm继承AlgorithmRuntime等一系列。
于是我们使用一种设计模式,聚合设计模式----这种方法只是客户使用端的排列使用,相对简单了许多
首先建一个接口AlgorithmInterface,都去实现它。
看代码:
一个主要的实现类,核心代码:
一些切面上的代码:
log
runtime:
客户应用的调用:package com.longkun.aop.test;
这就是聚合设计模式的思想,重要的是要记住其中的组织结构。
在spring中的AOP的实现工程呢,则是使用动态代理的方式,比聚合设计模式还要简单一些,实现过程没有去模仿。在这里就说明一下使用。
2、AOP的使用
AOP的使用,分为注解注入方式(@AspectJ)和配置文件注入方式,由于AOP的注解方式很少用,并有一些不方便,所以这里讲解一下xml配置文件的注入使用方式。
几个简单的概念:
切面(Aspect)是现实世界领域问题的抽象,除了包括属性、方法以外,同时切面中还包括切入点 Pointcut、增强(advice)等。
连接点(Join point):连接点也就是运用程序执行过程中需要插入切面模块的某一点
切入点(Pointcut):切入点指一个或多个连接点,可以理解成一个点的集合。切入点一般会跟连接点的上下文环境结合
增强或通知(Advice):定义了切面中的实际逻辑(即实现),是指在定义好的切入点处,所要执行的程序代码。
一个样例:
beans.xml
使用到动态的代理一定要用接口:
实现接口:
实现切面的类代码:
应用客户端实现:
打印结果:
beforeMain ... beforeMain
afterMain ... afterMain:
这两句话出现两次,是因为com.longkun.aop.test包及子包下,有多个方法。
<aop:before method="beforeMain" pointcut="execution(public * com.longkun.aop.test..*.*(..))"/>
将这句话改为:
<aop:before method="beforeMain" pointcut="execution(public * com.longkun.aop.test.Algorithm.*(..))"/>
beforeMain ... beforeMain 这句话就会只出现一次
痛苦啊!我们被困在办公室里了!一开门就走吧。只是可惜今天没有写这篇文章了!唉,计划不如变化快啊!
还没写这篇文章呢?就要催着走!
今天补上这一篇的内容:
目录:
1、AOP的原理
2、AOP的使用
1、AOP原理:
AOP编程是面向对象思维方式的有力补充。
面向切面编程就是在要运行的代码 前、后 加一些信息代码,而不影响原来的代码。
如果在框架中,没有AOP的这部分框架,我们自己也可以是实现面向切面编程----有两种比较好的方式:继承方式和组合设计模式
package com.longkun.aop.test; public class Algorithm { /** * @author longkun.wyb * 求一组数据的逆序数,归并排序 * @param args */ static int num = 0; public void main(){ System.out.println(2.00-1.10); System.out.printf("%.2f\n",2.00-1.10); int value[] = {0,10,100,45,39}; int left = 0; int right = value.length-1; mergeSort(value,left,right); System.out.println(num); for(int i = 0 ; i <= right; ++i){ System.out.print(" "+value[i]); } } private void mergeSort(int[] value,int left,int right){ if(left<right){ int middle = (left+right)/2; mergeSort(value,left,middle); mergeSort(value,middle+1,right); merge(value,left,middle,right); } } private void merge(int[] value,int left,int middle,int right){ int[] tmp = new int[100]; int k = left; int i = left; int j = middle+1; for(; i <= middle && j<= right ;){ if(value[i] > value[j]){ num+=middle-i+1; tmp[k++]=value[j++]; }else{ tmp[k++]=value[i++]; } } while(i<=middle){ tmp[k++]=value[i++]; } while(j<=right){ tmp[k++]=value[j++]; } for(i=left;i<=right;++i){ value[i]=tmp[i]; } } }
在这段代码前后加代码的话,可以继承这个类,调用super的方式:
package com.longkun.aop.test; public class AlgorithmLog extends Algorithm{ @Override public void main() { System.out.println("log... start ..."); super.main(); System.out.println("log... end ..."); } }
但是如过想在这段代码前后在加内容就要再继承它:
package com.longkun.aop.test; public class AlgorithmRuntime extends AlgorithmLog{ @Override public void main() { System.out.println("Run start ..."); long start = System.currentTimeMillis(); super.main(); long end = System.currentTimeMillis(); System.out.println("Run end..."+" 时间:"+(end-start)); } }
问题来了,你如过想让RunTime在前,Log再后,那改代码就很麻烦了。需要让Algorithm继承AlgorithmRuntime等一系列。
于是我们使用一种设计模式,聚合设计模式----这种方法只是客户使用端的排列使用,相对简单了许多
首先建一个接口AlgorithmInterface,都去实现它。
看代码:
package com.longkun.aop.test; public interface AlgorithmInterface { public void main(); }
一个主要的实现类,核心代码:
package com.longkun.aop.test; public class Algorithm implements AlgorithmInterface{ public void main(){ System.out.println("求一组数据的逆序数,归并排序"); } }
一些切面上的代码:
log
package com.longkun.aop.test; public class AlgorithmLog implements AlgorithmInterface{ AlgorithmInterface al = null; public AlgorithmLog(AlgorithmInterface algorithm){ this.al = algorithm; } @Override public void main() { System.out.println("log... start ..."); al.main(); System.out.println("log... end ..."); } }
runtime:
package com.longkun.aop.test; public class AlgorithmRuntime implements AlgorithmInterface{ AlgorithmInterface al = null; public AlgorithmRuntime(AlgorithmInterface algorithm) { this.al = algorithm; } @Override public void main() { System.out.println("Run start ..."); long start = System.currentTimeMillis(); al.main(); long end = System.currentTimeMillis(); System.out.println("Run end..."+" 时间:"+(end-start)); } }
客户应用的调用:package com.longkun.aop.test;
package com.longkun.aop.test; public class Client { public static void main(String[] args){ AlgorithmInterface al = new Algorithm(); AlgorithmInterface log = new AlgorithmLog(al); AlgorithmInterface runtime = new AlgorithmRuntime(log); runtime.main(); System.out.println("************************************************"); AlgorithmInterface runtime1 = new AlgorithmRuntime(al); AlgorithmInterface log1 = new AlgorithmLog(runtime1); log1.main(); } } 执行结果: Run start ... log... start ... 求一组数据的逆序数,归并排序 log... end ... Run end... 时间:0 ************************************************ log... start ... Run start ... 求一组数据的逆序数,归并排序 Run end... 时间:0 log... end ...
这就是聚合设计模式的思想,重要的是要记住其中的组织结构。
在spring中的AOP的实现工程呢,则是使用动态代理的方式,比聚合设计模式还要简单一些,实现过程没有去模仿。在这里就说明一下使用。
2、AOP的使用
AOP的使用,分为注解注入方式(@AspectJ)和配置文件注入方式,由于AOP的注解方式很少用,并有一些不方便,所以这里讲解一下xml配置文件的注入使用方式。
几个简单的概念:
切面(Aspect)是现实世界领域问题的抽象,除了包括属性、方法以外,同时切面中还包括切入点 Pointcut、增强(advice)等。
连接点(Join point):连接点也就是运用程序执行过程中需要插入切面模块的某一点
切入点(Pointcut):切入点指一个或多个连接点,可以理解成一个点的集合。切入点一般会跟连接点的上下文环境结合
增强或通知(Advice):定义了切面中的实际逻辑(即实现),是指在定义好的切入点处,所要执行的程序代码。
一个样例:
beans.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /> <bean id="algorithm" class="com.longkun.aop.test.Algorithm"></bean> <bean id="algorithmLog" class="com.longkun.aop.test.AlgorithmLog"/> <aop:config> <aop:aspect ref="algorithmLog"> <aop:before method="beforeMain" pointcut="execution(public * com.longkun.aop.test..*.*(..))"/> <!-- 第一个*代表任何返回类型,第二个*代表com.longkun.aop.test包以及子包的任何类,第三个*代码任何方法 --> <aop:after-returning method="afterReturnMain" pointcut="execution(public * com.longkun.aop.test.Algorithm.main(..))" returning="reval"/> <aop:after method="afterMain" pointcut="execution(public void com.longkun.aop.test..*.main(..))"/> <aop:after-throwing method="afterThrowingMain" pointcut="execution(public * com.longkun.aop.test.Algorithm.main(..))" throwing="ex"/> <aop:around method="aroundMain" pointcut="execution(public * com.longkun.aop.test..*.display(..))"/> </aop:aspect> </aop:config> </beans>
使用到动态的代理一定要用接口:
package com.longkun.aop.test; public interface AlgorithmInterface { public void main(); public void display(); }
实现接口:
package com.longkun.aop.test; public class Algorithm implements AlgorithmInterface{ public void display() { System.out.println("display......。。。。。。"); } public void main(){ System.out.println("求一组数据的逆序数,归并排序。。。。。。。"); } }
实现切面的类代码:
package com.longkun.aop.test; import org.aspectj.lang.ProceedingJoinPoint; public class AlgorithmLog{ public AlgorithmLog(){} public void beforeMain(){ System.out.println("beforeMain ... beforeMain"); } public void afterMain(){ System.out.println("afterMain ... afterMain:"); } public void afterReturnMain(String reval){ System.out.println("afterReturnMain ... afterReturnMain:"+reval); } public void afterThrowingMain(Exception ex){ System.out.println("afterThrowingMain:"+ex.getMessage()); } public void aroundMain(ProceedingJoinPoint joinPoint){ System.out.println("Aruound Before.."); try { joinPoint.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("Around After!!"); } }
应用客户端实现:
package com.nullf; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.longkun.aop.test.AlgorithmInterface; public class Client { public static void main(String[] args){ ApplicationContext acx = new ClassPathXmlApplicationContext("beans.xml"); AlgorithmInterface al = (AlgorithmInterface)acx.getBean("algorithm"); System.out.println("hello main"); al.main(); // al.display(); } }
打印结果:
hello main beforeMain ... beforeMain beforeMain ... beforeMain 求一组数据的逆序数,归并排序。。。。。。。 afterReturnMain ... afterReturnMain:null afterMain ... afterMain: afterMain ... afterMain:
beforeMain ... beforeMain
afterMain ... afterMain:
这两句话出现两次,是因为com.longkun.aop.test包及子包下,有多个方法。
<aop:before method="beforeMain" pointcut="execution(public * com.longkun.aop.test..*.*(..))"/>
将这句话改为:
<aop:before method="beforeMain" pointcut="execution(public * com.longkun.aop.test.Algorithm.*(..))"/>
beforeMain ... beforeMain 这句话就会只出现一次
相关文章推荐
- Spring基础学习(四)—AOP
- Spring学习历程 --- AOP基础之代理
- spring学习总结(九):AOP 基础及基于注解配置的AOP
- Spring3.X学习笔记5-SpringAOP基础
- [原]spring学习笔记9.1-Spring对Aop的支持-AOP基础篇
- spring 学习(1.2) 入门基础- AOP
- Spring学习笔记之SpringAOP基础
- Spring4学习:SpringAOP基础
- spring学习小结11——AOP基础
- spring 学习(1.3) 入门基础- AOP 实例
- Spring学习笔记之AOP基础
- spring学习笔记(15)——AOP基础
- spring学习历程---AOP基础
- Spring学习(八)-AOP基础以及日志
- spring 学习基础笔记 包括spring 的代理 JDK CGLIB 事物 AOP 以及各种注入
- spring 学习(1.4) 入门基础- AOP教程
- spring学习之AOP基础
- Spring基础学习教程(Spring AOP总结)-09
- Spring 学习笔记(12)—— AOP 基础
- Java动态代理学习【Spring AOP基础之一】