spring基础学习四(aop)

这里先占个位置,今天晚上下班后完成!


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

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

今天补上这一篇的内容:



目录:

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  这句话就会只出现一次




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值