【AOP的实现之SpringAop(一)】:spring和aspectj结合实现Aop的局限性,以及性能比较

AOP操作术语

【AOP的实现之SpringAop(一)】:spring和aspectj结合实现Aop的局限性,以及性能比较_第1张图片

Spring的aop操作

SpringAOP局限性

只能对spring管理的bean增加aop功能

1 在spring里面进行aop操作,使用aspectj实现
(1)aspectj不是spring一部分,和spring一起使用进行aop操作
(2)Spring2.0以后新增了对AspectJ支持
2 使用aspectj实现aop有两种方式
(1)基于aspectj的xml配置
(2)基于aspectj的注解方式

Aop操作准备

1 除了导入基本的jar包之外,还需要导入aop相关的jar

2 创建spring核心配置文件,导入aop的约束

【AOP的实现之SpringAop(一)】:spring和aspectj结合实现Aop的局限性,以及性能比较_第2张图片

使用表达式配置切入点

1 切入点:实际增强的方法

2 常用的表达式
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
(1)execution(* cn.itcast.aop.Book.add(..))
(2)execution(* cn.itcast.aop.Book.*(..))
(3)execution(* *.*(..))
(4) 匹配所有save开头的方法 execution(* save*(..))

访问修饰符指的是:public private等

Aspectj的aop操作

【AOP的实现之SpringAop(一)】:spring和aspectj结合实现Aop的局限性,以及性能比较_第3张图片

package cn.itcast.aop;

public class Book {

	public void add() {
		System.out.println("add...........");
	}
}

 

package cn.itcast.aop;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyBook {

	public void before1() {
		System.out.println("前置增强......");
	}
	
	public void after1() {
		System.out.println("后置增强......");
	}
	
	//环绕通知
	public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		//方法之前
		System.out.println("方法之前.....");
		
		//执行被增强的方法
		proceedingJoinPoint.proceed();
		
		//方法之后
		System.out.println("方法之后.....");
	}
}

 



	
	
	
	
	
	
	
		
		
		
		
		
			
			
			
			
			
			
		
	
	



【AOP的实现之SpringAop(一)】:spring和aspectj结合实现Aop的局限性,以及性能比较_第4张图片

1 基于aspectj的注解aop操作(会用)

1 使用注解方式实现aop操作
第一步 创建对象

package cn.itcast.aop;

public class Book {

	public void add() {
		System.out.println("add.............");
	}
}
@Aspect
public class MyBook {

	//在方法上面使用注解完成增强配置
	@Before(value="execution(* cn.itcast.aop.Book.*(..))")
	public void before1() {
		System.out.println("before..............");
	}
}

 

第二步 在spring核心配置文件中,开启aop操作

 




	
	
	
	
	
	
	



package cn.itcast.aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAop {

	@Test
	public void testDemo() {
		ApplicationContext context = 
				new ClassPathXmlApplicationContext("bean3.xml");
		Book book = (Book) context.getBean("book");
		book.add();
	}
}

【AOP的实现之SpringAop(一)】:spring和aspectj结合实现Aop的局限性,以及性能比较_第5张图片

AOP实战 

说了这么多理论,那AOP到底能做什么呢? AOP能做的事情非常多。

  • 性能监控,在方法调用前后记录调用时间,方法执行太长或超时报警。
  • 缓存代理,缓存某方法的返回值,下次执行该方法时,直接从缓存里获取。
  • 软件破解,使用AOP修改软件的验证类的判断逻辑。
  • 记录日志,在方法执行前后记录系统日志。
  • 工作流系统,工作流系统需要将业务代码和流程引擎代码混合在一起执行,那么我们可以使用AOP将其分离,并动态挂接业务。
  • 权限验证,方法执行前验证是否有权限执行当前方法,没有则抛出没有权限执行异常,由业务代码捕捉。 

4.1 Spring的AOP 
    Spring默认采取的动态代理机制实现AOP,当动态代理不可用时(代理类无接口)会使用CGlib机制。但Spring的AOP有一定的缺点,第一个只能对方法进行切入,不能对接口,字段,静态代码块进行切入(切入接口的某个方法,则该接口下所有实现类的该方法将被切入)。第二个同类中的互相调用方法将不会使用代理类。因为要使用代理类必须从Spring容器中获取Bean。第三个性能不是最好的,从3.3章节我们得知使用自定义类加载器,性能要优于动态代理和CGlib。 
可以获取代理类

Java代码  收藏代码

  1. public IMsgFilterService getThis()   
  2. {   
  3.         return (IMsgFilterService) AopContext.currentProxy();   
  4. }   
  5.   
  6. public boolean evaluateMsg () {   
  7.    // 执行此方法将织入切入逻辑   
  8. return getThis().evaluateMsg(String message);   
  9. }   
  10.   
  11. @MethodInvokeTimesMonitor("KEY_FILTER_NUM")   
  12. public boolean evaluateMsg(String message) {   

 不能获取代理类

Java代码  收藏代码

  1. public boolean evaluateMsg () {   
  2.    // 执行此方法将不会织入切入逻辑   
  3. return evaluateMsg(String message);   
  4. }   
  5.   
  6. @MethodInvokeTimesMonitor("KEY_FILTER_NUM")   
  7. public boolean evaluateMsg(String message) {   

 

 4.2 参考资料

  • Java 动态代理机制分析及扩展
  • CGlib的官方网站
  • ASM官方网站
  • JbossAOP
  • Java5特性Instrumenttation实践 

 

AOP 实现的性能比较

Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:

1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了
2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB

SpringAOP局限性

只能对spring管理的bean增加aop功能

AOP 底层技术比较

AOP技术 功能 性能 面向接口编程 编程难度 使用场合
直接编辑class 文件 完全控制类 无明显性能代价 不要求 高,要求对 class 文件结构和 Java 字节码有深刻了解 对class字节码结构深入了解,且只需要改动很小
JDK Instrument 完全控制类 无论是否改写,每个类装入时都要执行 hook 程序 不要求 高,要求对 class 文件结构和 Java 字节码有深刻了解 更适用于监控和控制虚拟机的行为
JDK Proxy 只能改写 method 反射引入性能代价 要求  
ASM 几乎能完全控制类 无明显性能代价 不要求 中,能操纵需要改写部分的 Java 字节码  

动态代理技术的层级关系

ASM –> cglib –> springAOP
ASM –> AspectJ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(【AOP,性能专题】)