1.先说动态代理(先把动态放下,先讲代理,代理也是23种设计模式中的一种代理模式,大家可以从海外代购理解,我想去海外买东西,得坐飞机,排队,付钱,回国,我觉得太麻烦,于是我只负责付钱,坐飞机,排队,回国都由代理类来做,我和代理类实现同一个接口,或者代理类继承我即可!这儿就牵扯出了java中的代理,说白了就是把付钱的方法进行了增强,对不对,付钱之前和之后做了很多事情,但是跟我本类没有关系)。
2.静态代理其实就是程序员手写的代理类,缺点很明显,一个代理只能代理一个类。
而动态代理可以根据要代理的目标不同生成不同的代理对象,也就是运行时才生成的,这也就相当于传参数,确实可以这样理解。
Object res = method.invoke(train, args);
注意这行代码,我可以直接通过invoke调用被代理的方法。
station.sell();
而不是像这样写死,对吧!
3.Java中经典的两种代理方式
*jdk动态代理,被代理的方法必须 在接口中有定义,也就是被代理对象必须实现了相应的接口。
*CGlib是通过生成一个子类 来继承 被代理的类,实现的动态代理,因此cglib不能代理被final修饰的类,是基于asm字节码实现的,也就是直接生成class文件。
这两种代理方式都是通过反射实现的,也就是根据类的全类名获取到类的属性。
有时间和兴趣也可以通过arthas来看下生成的代理对象。
明白了动态代理和反射接下来看aop
讲aop用经典的日志注解来讲
这就是一个切点,指向那个注解类 @Pointcut(“@annotation(com.jeeplus.aop.logging.annotation.ApiLog)”)
public void applicationPackagePointcut() {
// 方法为空,因为这只是一个切入点,实现在advices.
}
然后还有切面也就是一个切面类aspect
还有通知经典的环绕通知、前置通知、后置通知、返回通知、异常通知。
连接点joinpoint可以拿到业务方法的一些属性,并且调用业务方法执行。
Object result = joinPoint.proceed ( );
springaop和asjectj区别
asjectj支持编译时织入(静态代理)、加载时织入
springaop只支持运行时织入(首先尝试jdk动态代理,没有接口就用cglib)
据说aspectj的编译时织入比springaop的运行时织入性能要好。
还有就是aspectj是aop的完整解决方案,支持的切点比springaop更多。