之前写了一篇了:
https://blog.csdn.net/qq_19841133/article/details/109695223
代理设计模式
什么是代理设计模式
是一种结构型设计模式,为某个对象提供一个代理类,以控制对该对象的访问。
AOP(面向切面)就是用到这个设计模式。
静态代理
不重复写了
https://blog.csdn.net/qq_19841133/article/details/109695223
JDK动态代理
不重复写了
https://blog.csdn.net/qq_19841133/article/details/109695223
CGLIB动态代理
需要两个库
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/asm/asm -->
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
新建一个类CglibProxy,实现MethodInterceptor接口,重写intercept方法,在测试方法中实例化Enhancer类进行使用
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 房子
*
* @author uuz
* @date 2021/01/10
*/
interface House {
/**
* 买
*/
void buy();
}
/**
* 人
*
* @author uuz
* @date 2021/01/10
*/
class Person implements House {
/**
* 买
*/
@Override
public void buy() {
System.out.println("买房");
}
}
/**
* cglib代理
*
* @author uuz
* @date 2021/01/10
*/
class CglibProxy implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("中介找房源");
// 这个object就是代理后的对象
Object o1 = methodProxy.invokeSuper(o, objects);
System.out.println("买房结束");
return o1;
}
}
public class Test3 {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Person.class);
enhancer.setCallback(cglibProxy);
House house = (House) enhancer.create();
house.buy();
}
}
JDK动态代理的Cglib动态代理的区别
JDK动态代理是使用zaijava.lang.reflect.Proxy中的方法,这个方法在反射包中的。
而cglib方法是通过字节码加载的。
详细的说:
JDK动态代理利用反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理利用asm开源包,对代理对象的class文件加载,通过修改其字节码来生成子类来处理。
了解springAOP
- 如果目标对象实现了接口,默认情况下采用JDK的动态代理来实现AOP
- 如果目标对象实现了接口,可以强制使用cglib来实现AOP
- 如果目标对象没有实现接口,必须采用cglib,spring会在自动在jdk和cglib之间切换