0
点赞
收藏
分享

微信扫一扫

CglibProxy!


1.什么是CGlib?

        它是一个开源项目,可以在运行期间扩展Java类与实现Java接口。底层时通过使用一个小而快的字节码的处理nsm架来转换字节码生成新的类。

        代理类就是这么通过nsm生成的。

2.应用场景

        动态代理其所要增强的目标类可以不实现接口(任何业务接口);当然 亦可以用作实现了的业务接口。

3.代理生成的原理

        CGlib使用子类扩展父类的方式来生成代理对象,cglib会自动动态的生成目标类的子类作为代理类,并创建对象,即代理对象。

4.

        a.目标类不能是final的。

        b.目标类具有自己的参数构造器:如果一个子类具有子类,那么父类就必须拥有无参构造器。

MethodInterceptor (内调接口)——intercept方法————需要创建一个CglibProxy的接口,需要用到Enhancer增强器,借助它来创建代理对象。

5.

        当然普通类与动态Proxy的类的区别:

        普通类则是预存于一个。class文件中,而Proxy而是在Java.jvm虚拟机中实现运行时动态生成。还有就是CGLIB的动态代理使我们自己写的,而jdk的动态代理直接引用就行。

6.代码展示

(1)以下就是CGlib代理对象 的生成

public interface CglibProxy { 
// 用于创建代理对象

// targetClass:目标类

// mi:委托类对象

public static Object newProxyInstance(Class targetClass, MethodInterceptor mi) {

// 增强器

Enhancer enhancer = new Enhancer();

// 指定父类,即指定目标类

enhancer.setSuperclass(targetClass);

// 指定回调对象,即指定委托类对象

enhancer.setCallback(mi);

// 创建并返回代理对象

return enhancer.create();

}

(2)// 委托类
public class serviceProxyEntrust implements MethodInterceptor {
// 声明目标对象
// 目标类实现业务接口
/*
private ISomeService target;
public ServiceProxyEntrust(ISomeService target) {
super();
this.target = target;
}
*/
// 目标类没有实现业务接口
private serviceImple target;
public serviceProxyEntrust(serviceImple target2) {
super();
this.target = target2;
}

// 当执行代理对象的代理方法时,代理方法会调用该invoke()方法
// obj:代理对象
// method:目标方法
// args:目标方法参数列表
// proxy:目标方法的代理对象
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
String superName = proxy.getSuperName();
Signature signature = proxy.getSignature();

System.out.println("superName = " + superName);
System.out.println("signature = " + signature);
// 执行目标方法
Object result = method.invoke(target, args);
return result;
}}
(2)// 客户类
public class Client {
public static void main(String[] args) {
// 创建目标对象
// ISomeService target = new SomeServiceImpl();
serviceImple target = new serviceImple();
// 创建委托对象
serviceProxyEntrust mi = new serviceProxyEntrust(target);

// 创建代理对象
// ISomeService service = (ISomeService) CglibProxy.newProxyInstance(target.getClass(), mi);
serviceImple service = (serviceImple) CglibProxy.newProxyInstance(target.getClass(), mi);

// 调用代理对象的代理方法
String someResult = service.doSome(5, "月份");
System.out.println("someResult = " + someResult);
System.out.println("=========================");

}
}

举报
0 条评论