Spring 框架在运行时,通过字节码技术,在jvm创建的,运营在jvm内部,等程序结束后,会和jvm一起消失。
通过第三方动态字节码框架,在jvm中创建对应类的字节码,进而创建对象,当虚拟机结束,动态字节码跟着消失。==
结论:
动态代理不需要定义类文件,都是在jvm运行过程中创建的,所以不会造成静态代理,类文件数量过多,影响项目管理的问题。
第三方动态字节码框架:ASM,javassist ,cglib
Proxy.newProxyInstance(ClassLoader, Interfaces, handler);
参数1ClassLoader:借用一个类加载器,创建代理类,的class对象,进而可以创建代理对象。
参数2Interfaces:原始对象的接口,例如:
TestService testService = new TestServiceImpl();
//参数2Interfaces:testService.getClass().getInterfaces();
参数3:handler 即 invocationHandler
作用:用于书写额外功能,额外功能运行在原始方法之前 ,之后,抛出异常。
例如:
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------proxy log before --------");
//原始方法运行
Object ret = method.invoke(testService, args);
System.out.println("------proxy log after --------");
return ret;
}
};
上述代码中各个参数的含义:
返回值:Object:原始方法的返回值。
参数:proxy: 可忽略,代表的是代理对象;
method:额外功能所增加给的那个原始方法,可调用invoke()方法执行原始方法
args[]:原始方法的参数
前置条件:
一个接口和一个接口的实现类,例如:
接口:
public interface TestService {
boolean login(String username, String passoword);
}
实现类:
public class TestServiceImpl implements TestService {
@Override
public boolean login(String username, String passoword) {
System.out.println("username = " + username + "password = " + passoword);
return true;
}
}
开始编写动态代理:
public class TestProxy {
public static void main(String[] args) {
//1. 创建原始对象
TestService testService = new TestServiceImpl();
//2. 创建JDK动态代理
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------proxy log before --------");
//原始方法运行
Object ret = method.invoke(testService, args);
System.out.println("------proxy log after --------");
return ret;
}
};
/*
ClassLoader loader,借用一个类加载器 创建代理类的class对象 ,进而可以创建代理对象
Class>[] interfaces,
InvocationHandler h
*/
TestService testServiceProxy = (TestService) Proxy.newProxyInstance(TestServiceImpl.class.getClassLoader(), testService.getClass().getInterfaces(), handler);
testServiceProxy.login("123", "123");
}
运行结果:

CGlib创建动态代理的原理:继承关系创建代理对象,原始类作为类,代理类作为类,这样既可以保证2者法致,同时在代理类中提供新的实现(额外功能+原始法);
前置条件跟上面一样
public class TestCglib {
public static void main(String[] args) {
// 1. 创建原始对象
TestService testService = new TestService();
//2 .通过cglib创建动态代理对象
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(testService.getClass().getClassLoader());
enhancer.setSuperclass(testService.getClass());
MethodInterceptor methodInterceptor = (o, method, args1, methodProxy) -> {
//等同于 InvocationHandler ---invoke
System.out.println(" log= ");
Object invoke = method.invoke(testService, args1);
return invoke;
};
enhancer.setCallback(methodInterceptor);
TestService o = (TestService) enhancer.create();
o.login("yjy", "123");
}
}
运行结果:

若有错误,希望大佬指出。
对你有帮助给点个??再走呗。
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦