一,JDK动态代理原理:
1.步骤:
(1):获取被代理对象的引用,并且获取它的所有接口,反射获取
(2):JDK动态代理类重新生成一个新的类,同时新的类要实现被代理类的所有接口
(3):动态生成Java代码,新加的业务逻辑方法由一定的逻辑代码调用(在代码中体现)
(4):编译新生成的Java代码.class文件
(5):重新加载到JVM中运行
以上过程叫字节码重组。JDK有一个规范,在ClassPath下只要是以$开头的.class文件一般都是生成的。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* test.JDKProxy
* Description:
* date:3/28/2022 4:32 PM
*
* @author:chenweipeng
* @version:1.0
* @since JDK 1.8
*/
interface IPerson{
void findLove(String name);
}
class ZhaoLiu implements IPerson{
@Override
public void findLove(String name) {
System.out.print("找到了"+name);
System.out.println("符合赵六的标准");
}
}
public class JDKProxy implements InvocationHandler {
private Object target;
public Object getProxyObject(Object target){
this.target = target;
Class<?> clazz = target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(this.target, args);
after();
return invoke;
}
private void before(){
System.out.println("before");
}
private void after(){
System.out.println("after");
}
}
class Test08{
public static void main(String[] args) {
IPerson person = ((IPerson) (new JDKProxy().getProxyObject(new ZhaoLiu())));
person.findLove("凤姐");
}
}
before
找到了凤姐符合赵六的标准
after
二、CGLib动态代理
(1)JDK动态代理实现了被代理对象的接口,CGLib动态代理继承了被代理对象
(2)JDK动态代理和CGLib动态代理都在运行期间生成字节码,JDK动态代理直接写Class字节码,CGLib动态代理使用ASM框架写Class字节码。CGLib动态代理更加复杂,生成代理类的效率比JDK动态代理低
(3)JDK动态代理调用代理方法是通过反射机制调用的,CGLib动态代理使用过FastClass机制直接调用方法的,CGLib动态代理的执行效率更高
依赖:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>7.1</version>
</dependency>
package test;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* test.CGlibMeipo
* Description:
* date:3/28/2022 5:01 PM
*
* @author:chenweipeng
* @version:1.0
* @since JDK 1.8
*/
public class CGlibMeipo implements MethodInterceptor {
//private Object target;
public Object getInstance(Object o){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(o.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object o1 = methodProxy.invokeSuper(o, objects);
after();
return o1;
}
private void before(){
System.out.println("before");
}
private void after(){
System.out.println("after");
}
}
class Customer{
public void findLove(){
System.out.println("doing...");
}
}
class Test09{
public static void main(String[] args) {
((Customer) new CGlibMeipo().getInstance(new Customer())).findLove();
}
}
before
doing...
after