您的位置:首页 > 编程语言 > Java开发

spring基础学习四(aop)

2011-12-05 10:26 453 查看
这里先占个位置,今天晚上下班后完成!

痛苦啊!我们被困在办公室里了!一开门就走吧。只是可惜今天没有写这篇文章了!唉,计划不如变化快啊!

还没写这篇文章呢?就要催着走!

今天补上这一篇的内容:

目录:

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 这句话就会只出现一次
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: