前一节所说的静态代理和动态代理模式都是要求目标对象是实现一个接口的目标对象,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以使用以目标对象子类的方式类实现代理,这种方法就叫做:Cglib代理
1.Cglib说明
Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展。
Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口。它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)
Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
2.Cglib实现
Clinet:客户端调用
RealSubject、RealSubject2:无继承,真实角色
CglibSubject:继承MethodInterceptor,动态代理生成类
Client.java
public class Client {
public static void main(String[] args)
{
CglibSubject cglibSubject = new CglibSubject();
RealSubject realSubject = (RealSubject)cglibSubject.getInstance(new RealSubject());
realSubject.request();
RealSubject2 realSubject2 = (RealSubject2)cglibSubject.getInstance(new RealSubject2());
realSubject2.request2();
}
}
CglibSubject.java
public class CglibSubject implements MethodInterceptor {
private Object sub;
/**
* 创建代理对象
*
* @param sub
* @return
*/
public Object getInstance(Object sub) {
this.sub = sub;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.sub.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
@Override
// 回调方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
proxy.invokeSuper(obj, args);
log(sub.getClass().getName());
return null;
}
private void log(String className)
{
System.out.println("代理AOP切入--打印log--"+className);
}
}
RealSubject.java 和 RealSubject2.java
public class RealSubject{
public void request() {
System.out.println("From Real Subject1!");
}
}
public class RealSubject2{
public void request2() {
System.out.println("From Real Subject2!");
}
}
3.Cglib对比
类别 | 静态代理个数 | 动态代理个数 | Cglib动态代理 |
---|---|---|---|
抽象角色 | n | n | 0 |
真实角色 | n | n | n |
动态代理生成类 | n | 1 | 1 |