一:前序
一开始对动态代理都不懂,一直心里还是很惧怕这个概念,之前也学过,学过就忘了,现在想想之所以忘了,是因为平时在开发中也不会使用到动态代理,那回过头再想想,自己已经做了六年多的开发了,那为什么还要学习这个了,今天想想也许就是技多不压身,其实只有知道的多了,才会在用到的时候,用起来,我想也有种说法是用到的时候再学也可以,但是在平时的开发中,我们很少会用到,可能是我们不知道动态代理,如果知道也许会在平时中使用它。之所以今天想做个总结是想到动态代理还是有很大的用处,只是我之前不知道。
二:CGLIB介绍
下面做个总结,动态代理里面有两种方式,一种是jdk的动态代理,一种是cglib动态代理,这里做个cglib动态代理,jdk的动态代理,将单独写个专题来介绍
CGLIB是一个强大的高性能的代码生成包,CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类,当然不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉,在引入cglibjar包后,也会导入ASMjar包
三:CGLIB实现
springboot支持的事务方式:@EnableTransactionManagement 在启动方法入口的类中添加
spring支持方式 :<aop:aspectj-autoproxy proxy-target-class="true"/> 下面是 spring xml文件配置的方式
- 创建切面类 ,在切面类上加上 @AspectJ注解
- 定义空的方法method,这个方法的目的是为了获取其注解上的Pointcut(在是地方增加通知)
- 在类中定义前置通知和后置通知 和环绕性通知(这里是简单的是打印日志的方法,在实际的业务开发过程中,通过依赖的方式 可以增加复杂的逻辑处理)
@Aspect
public class Interceptor {
@Pointcut("execution(public * com.ymaodou.service..*.*(..))")
public void method() {
}
@Before("method()")
public void before() {
System.out.println(" before annotation 前置通知!");
}
@After("method()")
public void after() {
System.out.println(" after annotation 后置通知!");
}
@Around("method()")
public void around(ProceedingJoinPoint point) {
System.out.println("around annotation 前置通知!");
try {
point.proceed();
}
catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("around annotation后置通知!");
}
}
调用方式
package dynamic;
import dynamic.cglibproxy.DynamicMethodInterceptor;
import dynamic.jdkproxy.InvocationHandlerImpl;
import dynamic.service.DynamicedService;
import org.springframework.cglib.proxy.Enhancer;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* Created by Administrator on 2020/2/10.
*/
public class TestDyncamin {
public static void main(String args[]) {
//测试cglib动态代理 获取动态搭理的对象
Enhancer enhancer = new Enhancer();
//设置父类,所谓的父类就是被代理类
enhancer.setSuperclass( DynamicedObjectImpl.class );
//设置enhancer的回调对象,即是设置增强类
enhancer.setCallback( new DynamicMethodInterceptor() );
//创建代理对象
DynamicedObjectImpl proxy = (DynamicedObjectImpl) enhancer.create();
proxy.eat();
}
}
调试结果
I am before cglib!
我 在 吃饭 前 干什么 和 后干什么 !
I am after cglib!
个人理解
对于动态代理的理解就是特别适合,你接受一个原有的项目,在某一个模块原有的功能上加上新功能,但是你又"不敢"或者不想改动原有的代码,可以使用动态代理,只是在选择的时候,要知道自己要选择jdk的动态代理还是cglib的动态代理,其实用那种都一样,只要实现功能就行,可能对于初级程序员比较在意的是性能,其实没有多少差别,那个自己比较熟悉就用那个。
来源:CSDN
作者:yan0219n
链接:https://blog.csdn.net/xiao320321/article/details/104180258