Java中的动态代理
2021-06-09 03:03
标签:模式 pom callback iat fast 如何 @param 常见 enc java 设计模式 动态代理是相对就静态代理而言 是指可以在代码中通过调用的方式,为任何一个我们想要代理的类,生成代理,而不需要更改原有的代码 JDK代理需要被代理类必须要先实现一个接口(前提),代理类需要实现java.lang.reflect.InvocationHandler 接口。 被代理类必须需要先实现一个接口(前提) 被代理类 创建通用的代理类 代理类的使用 JDK动态代理采用字节码重组,重新生成对象来替代原始对象,以达到动态代理的作用。JDK动态代理生成对象的步骤如下: CGLib需要先引入cglib.jar,通过实现方法拦截器去实现动态代理(net.sf.cglib.proxy.MethodInterceptor) 需要被代理的类 创建被代理类 代理类的使用 通过上面,我们看到,cglib代理方式,代理类本身不需要实现任何接口,而是cglib新生成一个类,去继承代理类,methodProxy.invokeSuper()去调用父类中的业务逻辑,并返回结果,前后可以加上我们的业务代码。 在spring aop中提供了两种动态代理方式,那如何进行选择呢? Java中的动态代理 标签:模式 pom callback iat fast 如何 @param 常见 enc 原文地址:https://www.cnblogs.com/yanchuanbin/p/14503118.html设计模式——动态代理
简介
静态代理是指:代理类通过对被代理类的引用,在代理类中重构被代理对象中需要代理的方法(在调用被代理类的引用对象相应方法的前后,添加我们需要的操作),静态代理对原有代码不会产生任务改变,不会自动生成新的字节码,只需要新建代理类就行,而动态代理会在运行时动态生成代码,取消了对被代理类的扩展限制,遵循开闭原则。
静态代理结构(代码)如下:
class Student {
public void study() {
System.out.println("I am studying");
}
}
class StudentStudyProxy {
private Student student;
public StudentStudyProxy(Student student) {
this.student = student;
}
public void study() {
before();
student.study();
after();
}
private void before() {
System.out.println("before study");
}
private void after() {
System.out.println("after study");
}
}
动态代理
动态代理作为spring中极其常见的一种设计模式,可以说贯穿着整个spring 生态,spring 代表作 aop,今天就一起来学习一下,java 的动态代理动态代理的分类
JDK动态代理
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
public interface Study {
/**
* 学习
*/
public void study();
}
public class Student implements Study{
/**
* 具体实现
*/
@Override
public void study() {
}
}
//泛型T必须是被代理类所实现的接口的类型
public class ObjectProxy implements InvocationHandler {
Object object;
/**
* 通用的jdk动态代理,只需要传入需要被代理类的类类型,这个类必须实现了T
*
* @param clazz 需要被代理的类 类型
* @return
*/
public
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
Study studentProxy = new ObjectProxy().getInstance(Student.class);
studentProxy.study();
}
原理分析:
1.获取被代理对象的引用,并且获取它的所有接口(通过反射获取);
2.JDK动态代理类重新生成一个新的类,在新的类里面实现被代理类实现的所有接口;
3.动态生成java代码,新加的 after 和 before业务添加到新生成的类中;
4.编译新生成的java代码,生成class文件;
5.重新将class文件加载到JVM中运行。
CGLib动态代理
maven pom引入cglib
class Student {
public void study() {
System.out.println("I am studying!!");
}
}
class ObjectProxy implements MethodInterceptor {
/**
* 根据传入类型,返回同样的类型,因为代理类实际上是创建的一个被代理类的子类
* @param clazz
* @param
public static void main(String[] args) {
Student studentProxy = new ObjectProxy().getInstance(Student.class);
studentProxy.study();
}
JDK动态代理和CGLib代理对比
1.JDK动态代理新生成的类实现了被代理对象所实现的接口,CGLib代理是继承了被代理对象;
2.JDK动态代理和CGLib代理都是在运行期间生成字节码,JDK动态代理直接写Class字节码,CGLib代理使用ASM框架写Class字节码,CGLib底层更加复杂;
3.JDK动态代理方法是通过反射机制调用的,而CGLib代理是通过FastClass机制直接调用方法,CGLib理论上执行效率更高。
Spring AOP中的动态代理
默认选择使用规则: 1.当Bean有实现接口时,Spring就会使用JDK动态代理;
2.当Bean没有实现接口时,Spring就会选择CGLib代理;
Spring可以通过配置强制使用CGLib代理方式。