AOP的基础是Java动态代理

Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及CGLIB动态代理。


静态代理:
	代理类与被代理类实现同一个接口,在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。


静态代理编译前就需要实现与被代理类相同的接口,动态代理只有运行时才知道针对哪个接口、哪个被代理类创建代理类。

JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反射机制在运行时创建代理类的。 
其实在动态代理中,核心是InvocationHandler。

	Proxy类中的newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)	//创建代理类实例
	Class<?> cl = getProxyClass0(loader, intfs);return proxyClassCache.get(loader, interfaces);	//产生代理类Class对象
	byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);	//字节码生成


CGLIB动态代理机制:

	CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。
	在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。

	创建代理对象的几个步骤:
		生成代理类的二进制字节码文件;
		加载二进制字节码,生成Class对象( 例如使用Class.forName()方法 );
		通过反射机制获得实例构造,并创建代理类对象。

	CGLIB中,方法的调用并不是通过反射来完成的,而是直接对方法进行调用:
		FastClass对Class对象进行特别的处理,比如将会用数组保存method的引用。

AOP 总结

我们传统的编程方式是垂直化的编程,即A–>B–>C–>D这么下去,一个逻辑完毕之后执行另外一段逻辑。
但是AOP提供了另外一种思路,它的作用是在业务逻辑不需要做任何的改动的情况下对业务代码的功能进行增强。
这种编程思想的使用场景有很多,例如事务提交、方法执行之前的权限检测、日志打印、方法调用事件等。


如果有一段逻辑重复的代码:
	普通方式,将代码直接写在目标对象中,造成代码冗余。如果Dao有其它实现类,那么必须新增一个类去包装该实现类,这将导致类数量不断膨胀
	装饰者方式:输出日志的逻辑还是无法复用(接口的每个方法都需要被装饰),输出日志的逻辑与代码有耦合。
	使用装饰器模式可以说是对使用原生代码的一种改进,使用Java代理可以说是对于使用装饰器模式的一种改进。


AOP实现原理:
    1. 加载 Bean 定义的时候应该有过特殊的处理
    2. getBean() 的时候应该有过特殊的处理 

    createAopProxy():
        对类生成代理使用CGLIB
        对接口生成代理使用JDK原生的Proxy
        可以通过配置文件指定对接口使用CGLIB生成代理

使用详解