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("=========================");

}
}

猜你喜欢

转载自blog.csdn.net/qq_40406929/article/details/79854849