`

实现AOP------Spring AOP

 
阅读更多


AOP系列文章:
      Spring AOP:
http://ray-yui.iteye.com/blog/2024759
               CGLIB:
http://ray-yui.iteye.com/blog/2026426
          Javassist:
http://ray-yui.iteye.com/blog/2029261


什么是AOP?
      AOP是对传统面向对象开发的一种有效的补充,在AOP中概念非常多,请容许笔者省略数千字的概念,只举出一个示例,面向对象中的类就好比是士兵,我们编写每个类就等同于为每个士兵增加装备和训练士兵的体能,从而达到可以上战场打仗的目的,然而有一天AOP这个魔法师出现了,打开了一个魔法门,告诉每个士兵(类),不用再每个士兵单独这样训练了(编码),从我这个魔法门(切面)走过就能增强士兵自身的能力,而这种方式,就是AOP,面向切面编程


AOP的实现方式:
      Spring中有AOP的实现,但Spring的AOP更多是借鉴了AspectJ的方式,SpringAOP是基于动态代理的,所以只是方法级别的连接点模型,无法做到例如字段或构造函数的接入点,无法让我们创建更细粒度的通知,若然读者有需要更精确的AOP,请考虑使用AspectJ或JBoss的AOP实现


SpringAOP使用(基于XML)

Java代码 复制代码 收藏代码
  1. package com.accentrix.ray;  
  2.   
  3. import org.aspectj.lang.ProceedingJoinPoint;  
  4. package com.accentrix.ray;  
  5.   
  6. import org.aspectj.lang.ProceedingJoinPoint;  
  7.   
  8. /* 
  9.  * 声明切面(Aspect) 
  10.  */  
  11. public class Advice {  
  12.   
  13.     // 前置执行方法  
  14.     public void beforeMethod() {  
  15.         System.out.println("method before execute");  
  16.     }  
  17.   
  18.     // 后置执行方法  
  19.     public void afterMethod() {  
  20.         System.out.println("method after execute");  
  21.     }  
  22.   
  23.     // 抛出异常时方法  
  24.     public void exceptionMethod() {  
  25.         System.out.println("method throw exception execute");  
  26.     }  
  27.   
  28.     // 环绕通知  
  29.     public void aroundMethod(ProceedingJoinPoint joinPoint) {  
  30.         /* 
  31.          * 环绕通知就类似Filter,在一个方法中包含开始,执行,结束,抛出异常 , 
  32.          * 甚至可以不调用joinPoint的proceed方法执行真实逻辑 亦可以多次调用 
  33.          * ,全由开发者业务逻辑决定 
  34.          */  
  35.         try {  
  36.             System.out.println("before");  
  37.             joinPoint.proceed();  
  38.             System.out.println("after");  
  39.         } catch (Throwable e) {  
  40.             e.printStackTrace();  
  41.             System.out.println("throw exception");  
  42.         }  
  43.     }  
  44.   
  45.     // 接受参数通知  
  46.     public void hasParamterAfterMethod(String name) {  
  47.         System.out.println("before method " + name);  
  48.     }  
  49. }  
package com.accentrix.ray;

import org.aspectj.lang.ProceedingJoinPoint;
package com.accentrix.ray;

import org.aspectj.lang.ProceedingJoinPoint;

/*
 * 声明切面(Aspect)
 */
public class Advice {

	// 前置执行方法
	public void beforeMethod() {
		System.out.println("method before execute");
	}

	// 后置执行方法
	public void afterMethod() {
		System.out.println("method after execute");
	}

	// 抛出异常时方法
	public void exceptionMethod() {
		System.out.println("method throw exception execute");
	}

	// 环绕通知
	public void aroundMethod(ProceedingJoinPoint joinPoint) {
		/*
		 * 环绕通知就类似Filter,在一个方法中包含开始,执行,结束,抛出异常 ,
		 * 甚至可以不调用joinPoint的proceed方法执行真实逻辑 亦可以多次调用
		 * ,全由开发者业务逻辑决定
		 */
		try {
			System.out.println("before");
			joinPoint.proceed();
			System.out.println("after");
		} catch (Throwable e) {
			e.printStackTrace();
			System.out.println("throw exception");
		}
	}

	// 接受参数通知
	public void hasParamterAfterMethod(String name) {
		System.out.println("before method " + name);
	}
}

 

Xml代码 复制代码 收藏代码
  1. <!-- 声明Bean -->  
  2. <bean id="advice" class="com.accentrix.ray.Advice" />  
  3.   
  4. <!-- 配置AOP -->  
  5. <aop:config>  
  6.     <!-- 引用注册的Bean ID -->  
  7.     <aop:aspect ref="advice">  
  8.         <!-- 声明切入点,过滤service下的所有类型和所有方法,不限制参数和返回类型 -->  
  9.         <aop:pointcut expression="execution(* com.accentrix.ray.service.*.*(..))"  
  10.             id="servicePoincut" />  
  11.   
  12.         <!-- 引用servicePoincut的切入点,调用advice的beforeMethod方法进行前置处理 -->  
  13.         <aop:before pointcut-ref="servicePoincut" method="beforeMethod" />  
  14.   
  15.         <!-- 引用servicePoincut的切入点,调用advice的afterMethod方法进行后置处理 -->  
  16.         <aop:after pointcut-ref="servicePoincut" method="afterMethod" />  
  17.   
  18.         <!-- 引用servicePoincut的切入点,调用advice的exceptionMethod方法进行异常处理 -->  
  19.         <aop:after-throwing pointcut-ref="servicePoincut"  
  20.             method="exceptionMethod" />  
  21.   
  22.         <!-- 引用servicePoincut的切入点,调用advice的aroundMethod方法进行环绕处理 -->  
  23.         <aop:around pointcut-ref="servicePoincut" method="aroundMethod" />  
  24.   
  25.         <!-- 使用如下pointcut即可为advice传递调用真实业务时传递的参数 -->  
  26.         <aop:after  
  27.             pointcut="execution(* com.accentrix.ray.service.*.*(String)) and args(name)"  
  28.             method="hasParamterAfterMethod" />  
  29.     </aop:aspect>  
  30. </aop:config>  
<!-- 声明Bean -->
<bean id="advice" class="com.accentrix.ray.Advice" />

<!-- 配置AOP -->
<aop:config>
	<!-- 引用注册的Bean ID -->
	<aop:aspect ref="advice">
		<!-- 声明切入点,过滤service下的所有类型和所有方法,不限制参数和返回类型 -->
		<aop:pointcut expression="execution(* com.accentrix.ray.service.*.*(..))"
			id="servicePoincut" />

		<!-- 引用servicePoincut的切入点,调用advice的beforeMethod方法进行前置处理 -->
		<aop:before pointcut-ref="servicePoincut" method="beforeMethod" />

		<!-- 引用servicePoincut的切入点,调用advice的afterMethod方法进行后置处理 -->
		<aop:after pointcut-ref="servicePoincut" method="afterMethod" />

		<!-- 引用servicePoincut的切入点,调用advice的exceptionMethod方法进行异常处理 -->
		<aop:after-throwing pointcut-ref="servicePoincut"
			method="exceptionMethod" />

		<!-- 引用servicePoincut的切入点,调用advice的aroundMethod方法进行环绕处理 -->
		<aop:around pointcut-ref="servicePoincut" method="aroundMethod" />

		<!-- 使用如下pointcut即可为advice传递调用真实业务时传递的参数 -->
		<aop:after
			pointcut="execution(* com.accentrix.ray.service.*.*(String)) and args(name)"
			method="hasParamterAfterMethod" />
	</aop:aspect>
</aop:config>



      SpringAOP基于Annotation方式

Xml代码 复制代码 收藏代码
  1. <!-- 需要在applicationContext.xml中增加如下配置 -->  
  2. <aop:aspectj-autoproxy />  
<!-- 需要在applicationContext.xml中增加如下配置 -->
<aop:aspectj-autoproxy />

 

Java代码 复制代码 收藏代码
  1. package com.accentrix.ray;  
  2.   
  3. import org.aspectj.lang.ProceedingJoinPoint;  
  4. import org.aspectj.lang.annotation.After;  
  5. import org.aspectj.lang.annotation.AfterThrowing;  
  6. import org.aspectj.lang.annotation.Around;  
  7. import org.aspectj.lang.annotation.Aspect;  
  8. import org.aspectj.lang.annotation.Before;  
  9. import org.aspectj.lang.annotation.Pointcut;  
  10.   
  11. @Aspect  
  12. public class AnnotationAdvice {  
  13.   
  14.     // 声明切入点  
  15.     @Pointcut("execution(* com.accentrix.ray.service.*.*(..))")  
  16.     public void myPointcut() {  
  17.   
  18.     }  
  19.   
  20.     // 可声明多个切入点  
  21.     @Pointcut("execution(* com.accentrix.ray.service.*.*(String) and args(name)")  
  22.     public void hasParamterPointcut(String name) {  
  23.   
  24.     }  
  25.   
  26.     // 注解形式前置通知  
  27.     @Before("myPointcut()")  
  28.     public void beforeMethod() {  
  29.         System.out.println("before method execute");  
  30.     }  
  31.   
  32.     // 注解形式后置通知  
  33.     @After("myPointcut()")  
  34.     public void afterMethod() {  
  35.         System.out.println("after method execute");  
  36.     }  
  37.   
  38.     // 注解形式异常通知  
  39.     @AfterThrowing("myPointcut()")  
  40.     public void exceptionMethod() {  
  41.         System.out.println("method throw exception execute");  
  42.     }  
  43.   
  44.     // 注解形式环绕通知  
  45.     @Around("myPointcut()")  
  46.     public void aroundMethod(ProceedingJoinPoint joinPoint) {  
  47.         try {  
  48.             System.out.println("before");  
  49.             joinPoint.proceed();  
  50.             System.out.println("after");  
  51.         } catch (Throwable e) {  
  52.             e.printStackTrace();  
  53.             System.out.println("throw exception");  
  54.         }  
  55.     }  
  56.   
  57.     // 注解形式传递参数给通知  
  58.     @Before("hasParamterPointcut(name)")  
  59.     public void hasParamterBeforeMethod(String name) {  
  60.         System.out.println("before method execute " + name);  
  61.     }  
  62. }  
package com.accentrix.ray;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AnnotationAdvice {

	// 声明切入点
	@Pointcut("execution(* com.accentrix.ray.service.*.*(..))")
	public void myPointcut() {

	}

	// 可声明多个切入点
	@Pointcut("execution(* com.accentrix.ray.service.*.*(String) and args(name)")
	public void hasParamterPointcut(String name) {

	}

	// 注解形式前置通知
	@Before("myPointcut()")
	public void beforeMethod() {
		System.out.println("before method execute");
	}

	// 注解形式后置通知
	@After("myPointcut()")
	public void afterMethod() {
		System.out.println("after method execute");
	}

	// 注解形式异常通知
	@AfterThrowing("myPointcut()")
	public void exceptionMethod() {
		System.out.println("method throw exception execute");
	}

	// 注解形式环绕通知
	@Around("myPointcut()")
	public void aroundMethod(ProceedingJoinPoint joinPoint) {
		try {
			System.out.println("before");
			joinPoint.proceed();
			System.out.println("after");
		} catch (Throwable e) {
			e.printStackTrace();
			System.out.println("throw exception");
		}
	}

	// 注解形式传递参数给通知
	@Before("hasParamterPointcut(name)")
	public void hasParamterBeforeMethod(String name) {
		System.out.println("before method execute " + name);
	}
}



总结:AOP对面向对象的士兵式编程提供了更好的补充,亦在广大的开源框架有显著的效果,例如Spring Security就以AOP为核心,在业务程序开发当中AOP亦到处存在,例如拦截并缓存关于菜单和数据字典的数据,例如声明式事务,而Annotation的出现更加为快速便捷开发提供了很好的支持,从上面两种方式对比就得出Annotation的声明更加简洁方便,所以在业务当中有需要使用自定义的AOP建议采用Annotation的方式,但XML文件的方式亦必须掌握,因为我们时常需要使用到其他框架提供的切面

分享到:
评论

相关推荐

    开发工具 spring-aop-4.3.6.RELEASE

    开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    spring-aop-5.2.0.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.2.0.RELEASE.jar; 赠送原API文档:spring-aop-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.2.0.RELEASE.pom;...

    spring-aop-5.0.8.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.0.8.RELEASE.jar; 赠送原API文档:spring-aop-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.8.RELEASE.pom;...

    spring-aop-5.3.10-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.10.jar; 赠送原API文档:spring-aop-5.3.10-javadoc.jar; 赠送源代码:spring-aop-5.3.10-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.10.pom; 包含翻译后的API文档:spring...

    spring-aop-jar

    aopalliance.jar、spring-aop-4.1.6.RELEASE.jar、spring-aspects-4.1.6.RELEASE.jar

    spring-aop-3.2.5.RELEASE.jar ;spring-aop-3.2.5.jar

    spring-aop-3.2.5.RELEASE.jar

    spring-aop-4.0.4.RELEASE

    spring-aop-4.0.4.RELEASE 的jar包,亲测可用。。。。

    spring-aop-5.1.3.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.1.3.RELEASE.jar; 赠送原API文档:spring-aop-5.1.3.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.1.3.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.1.3.RELEASE.pom;...

    Spring5 框架 ---- AOP ---- 代码

    Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 ...

    spring-aop-4.2.2.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-4.2.2.RELEASE.jar; 赠送原API文档:spring-aop-4.2.2.RELEASE-javadoc.jar; 赠送源代码:spring-aop-4.2.2.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-4.2.2.RELEASE.pom;...

    spring-aop-5.0.4.RELEASE.jar

    spring-aop-5.0.4.RELEASE.jar。

    spring-aop-3.2.0.RELEASE.jar

    spring-aop-3.2.0.RELEASE.jar,一个Spring中AOP的jar包

    spring-aop-2.0.8.jar

    spring-aop-2.0.8.jar

    spring-aop-5.3.12-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.12.jar; 赠送原API文档:spring-aop-5.3.12-javadoc.jar; 赠送源代码:spring-aop-5.3.12-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.12.pom; 包含翻译后的API文档:spring...

    spring-aop-5.0.10.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.0.10.RELEASE.jar; 赠送原API文档:spring-aop-5.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.10.RELEASE....

    spring-aop-5.0.1.RELEASE.jar

    spring-aop-5.0.1.RELEASE.jar

    spring-aop-5.1.0.RELEASE.jar

    spring-**core**-4.3.6.RELEASE.jar :包含spring框架基本的核心工具类,spring其他组件都要用到这个包里的类,其他组件的基本核心 spring-**beans**-4.3.6.RELEASE.jar:所有应用都要用到的jar包,它包含访问配置...

    spring-aop-5.3.15-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

    spring-aop-5.3.15-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

Global site tag (gtag.js) - Google Analytics