动态代理详解
1,jdk动态代理
jdk动态代理,需要有顶层接口才能实现,mybatis的mapper文件,使用了动态生成字节码技术
public interface IStudentService {
/**
* 交学费
*/
void pay();
/**
* 上课
*/
void attendClass();
}package org.lht.boot.lang.proxy;
public class StudentServiceImpl implements IStudentService {
@Override
public void pay() {
System.out.println("交学费");
}
@Override
public void attendClass() {
//先交学费
pay();
System.out.println("开始上学");
}
}
创建代理类:
package org.lht.boot.lang.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class StudentAdvice implements InvocationHandler {
private IStudentService target;
public StudentAdvice(IStudentService target) {
this.target = target;
}
/**
* 代理方法, 每次调用目标方法时都会进到这里
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
return method.invoke(target, args);
}
/**
* 前置增强
*/
private void before() {
System.out.println("对学生身份进行验证.");
}
}@Test
public void test03() {
//创建目标对象
IStudentService target = new StudentServiceImpl();
//创建代理对象
IStudentService proxy = (IStudentService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),//代理对象
new StudentAdvice(target)//做什么事情
);
//只能代理对象
proxy.attendClass();
}
运行结果:
对学生身份进行验证.交学费
开始上学
cglib动态代理
cglib动态代理,可以实现没有接口的类,使用了动态生成字节码技术,不能对final类继承
package org.lht.boot.lang.proxy;/**
* @author LiHaitao
* @description
* @date 2020/8/17 14:06
**/
public class StudentMethodInterceptorService {
public void pay() {
System.out.println("交学费");
}
}package org.lht.boot.lang.proxy;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author LiHaitao
* @description
* @date 2020/8/17 14:04
**/
public class DemoMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
before();
return methodProxy.invokeSuper(o, args);
}
/**
* 前置增强
*/
private void before() {
System.out.println("对学生身份进行验证.");
}
}@Test
public void test02() {
StudentMethodInterceptorService studentMethodInterceptorService = new StudentMethodInterceptorService();
StudentMethodInterceptorService proxy = (StudentMethodInterceptorService) Enhancer.create(studentMethodInterceptorService.getClass(),
new DemoMethodInterceptor());
proxy.pay();
}
运行结果:
对学生身份进行验证.交学费
spring中:
/*** 当Bean实现接口时,Spring就会用JDK的动态代理
* 当Bean没有实现接口时,Spring使用CGLib来实现
* 可以强制使用CGLib(在Spring配置中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>)
* <p>
* <p>
* 使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,在JDK1.6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
* 在JDK1.6、JDK1.7、JDK1.8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于CGLib代理效率,只有当进行大量调用的时候,JDK1.6和JDK1.7比CGLib代理效率低一点,但是到JDK1.8的时候,JDK代理效率高于CGLib代理
*/
问题1:如何代理一个final并且没有实现接口的类?
* 我直接把一个代理类的源代码用字符串拼出来,然后基于这个字符串调用JDK的Compiler(编译期)API,动态的创建一个新的.java文件,然后动态编译这个.java文件,这样也能得到一个新的代理类。
代理模式-动态代理详解(JDK动态代理和CGLIB动态代理)jdk cglib动态代理
静态代理,JDK动态代理,Cglib动态代理详解jdk动态代理
Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理jdk静态代理和动态代理
静态代理、动态代理,以及动态代理的调用说明静态代理和动态代理
#yyds干货盘点# 设计模式之静态代理,jdk动态代理,cglib动态代理的区别jdk静态代理和动态代理
代理模式-动态代理(基于接口,JDK动态代理)jdk动态代理和cglib动态代理
代理模式-静态代理模式 代理模式-动态代理(基于接口,JDK动态代理)动态代理是代理模式吗
【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )动态代理是代理模式吗