Spring-AOP讲解-附带实例

spring aop


aop是由java动态代理、cglib(cglib内封装了ASM字节码处理框架)、aspectj面向切面框架组成。
aop中包含了通过接口实现的JDK动态代理 和 通过目标类实现的cglib代理


java 动态代理--JDK动态代理只能对实现了接口的类生成代理,而不能针对类 ,通过实现InvocationHandler接口来代理类。
代理分为静态代理和动态代理,静态代理是在编译时就将接口、实现类、代理类一股脑儿全部手动完成,
但如果我们需要很多的代理,每一个都这么手动的去创建实属浪费时间,而且会有大量的重复代码,
此时我们就可以采用动态代理,动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,
来完成具体的功能。

其实方法直接调用就可以完成功能,为什么还要加个代理呢?
原因是采用代理模式可以有效的将具体的实现与调用方进行解耦,通过面向接口进行编码完全将具体的实现隐藏在内部。

CGLIB--代理类通过MethodInterceptor接口实现代理
cglib是一个高性能的代码生成包 
CGLIB可以在运行期扩展Java类与实现Java接口,cglib封装了asm,可以在运行期动态生成新的 class,cglib用于AOP,
jdk中的代理必须基于接口,cglib却没有这个限制。

ASM---
ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM可以直接产生二进制class文件,
也可以在类被加载入Java虚拟机之前动态改变类行为。Java class被存储在严格格式定义的.class文件里,
这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。
ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。


AspectJ--aop通过注解@AspectJ来实现
AspectJ是一个面向切面的框架,
AspectJ是一个代码生成工具(Code Generator),有一个用来生成遵守Java字节编码规范的Class文件的编译器。
AspectJ语法就是用来定义代码生成规则的语法。
AspectJ的表达式实例--
execution(public * *(..)):任意public方法
execution(public * com.mycompany..*.*(..)):com.mycompany包下任意子包的所有类的所有public 方法


大致运行过程
一、AspectJ从文件列表里取出所有的文件名,然后读取这些文件,进行分析。 
二、AspectJ发现一些文件含有aspect的定义
三、AspectJ根据这些aspect代码生成规则,修改添加你的源代码。
未修改前
public static void main(String args[])  
{  
    Speaker speaker = new Speaker();  
     
    speaker.speak();  
    
}  
修改后的源代码
public static void main(String args[])  
{  
    Speaker speaker = new Speaker();  
    AspectObserver.aspectOf().ajc$before$test_aspectj_AspectObserver$1$b2b6354();//多了这行  
    speaker.speak();  
    AspectObserver.aspectOf().ajc$afterReturning$test_aspectj_AspectObserver$2$b2b6354();//多了这行  
}  


SpringAop全自动代理实例

/**
 * 测试类
 * @author Administrator
 *
 */
public void test() {
	//启动spring上下文环境
	ApplicationContext context = new ClassPathXmlApplicationContext("spring/spring.xml");
	SayHello hello = (SayHello) context.getBean("sayHelloImpl");
	hello.sayHello("aaa");
}

/**
 * 测试接口
 * @author Administrator
 *
 */
public interface SayHello {
	public void sayHello(String name);
}

/**
 * 全自动AOP代理
 * @author Administrator
 *
 */
@Component
public class SayHelloImpl implements SayHello {

	@Override
	public void sayHello(String name) {
		System.out.println("你好"+name);
	}
}

/**
 * 自定义切面
 * Aspect是一个用java实现的解决advice使用太麻烦问题
 * Aspect:多个advice+多个连接点和切入点-最后执行表达式
 * @author Administrator
 *
 */
@Aspect
@Component
public class MyAspect {
	
	
	public MyAspect() {
		
	}

	//环绕通知
	@Around("execution(* com.yd.autoProxy.SayHelloImpl.*(..))")
	public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable{
		beforeAdvice();
		Object object = joinPoint.proceed();
		afterAdvice();
		return object;
	}
	
	private void beforeAdvice(){
		System.out.println("环绕前置增强");
	}
	private void afterAdvice(){
		System.out.println("环绕后置增强");
	}
}
//xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 扫描包加载实现类 -->
	<context:component-scan base-package="com.yd.autoProxy"></context:component-scan>
	<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>


打印结果

环绕前置增强
你好aaa
环绕后置增强


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值