对于动态代理,如果没有定义代理类接口,而只是定义了代理类,那么此时JDK动态代理就无法使用了,因为JDK动态代理要求必须定义接口,它是对接口进行代理的,现在没有定义接口,那么自然就不能使用JDK动态代理了。
这时,我们就可以使用CGLIB动态代理来实现。
CGLIB是一个功能强大,高性能的代码生成包(CGLIB就是用来生成代码的,它也是在内存中动态的去生成的)
因为CGLIB是第三方提供的包,所以我们需要在maven工程中引入对应jar包:
<!--CGLIB-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
接下来,CGLIB动态代理代码实现:
新建被代理类,我们这里用NaiKeCloth(耐克服装厂)举例。此时并不需要再新建Cloth接口,因为我们现在是要使用CGLIB进行代理
package com.hxk.pattern.proxy.cglib_proxy.lx;
/**
* 被代理类:耐克服装厂
*
* @author ***
* @create 2022-05-20 20:17
*/
public class NaiKeCloth {
public void makeCloth(String type){
System.out.println("制作服装:" + type);
}
public String brand(){
return "我的品牌是:耐克";
}
}
新建工厂类,即ProxyFactory,该工厂就是用来获取代理对象的,所以我们应该在该工厂类中定义一个获取代理对象的方法,此时,使用CGLIB进行代理的话,获得的代理类就是目标对象所属类的子类。
使用CGLIB来进行代理:
- 创建Enhancer类对象,该类类似于JDK动态代理中的Proxy类。它就是用来获取代理对象的。注意该类是属于CGLIB里面的,所以我们要导入相对应的包。
- 设置父类的字节码对象。使用CGLIB生成的代理类是属于目标类的子类的,也就是说代理类是要继承自目标类的。
- 设置回调函数。
ProxyFactory代码实现:
package com.hxk.pattern.proxy.cglib_proxy.lx;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author ***
* @create 2022-05-20 20:19
*/
public class ProxyFactory<T> implements MethodInterceptor {
private T obj;
public ProxyFactory(T obj) {
this.obj = obj;
}
public T getProxy(){
// 1. 创建Enhancer类对象,它类似于咱们JDK动态代理中的Proxy类,该类就是用来获取代理对象的
Enhancer enhancer = new Enhancer();
// 2. 设置父类的字节码对象。为啥子要这样做呢?因为使用CGLIB生成的代理类是属于目标类的子类的,也就是说代理类是要继承自目标类的
enhancer.setSuperclass(obj.getClass());
// 3. 设置回调函数
enhancer.setCallback(this);
// 4. 创建代理对象
return (T) enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if (method.getName().equals("makeCloth")){
System.out.println("制作服装前的准备.........");
}
Object invoke = method.invoke(obj, objects);
if (method.getName().equals("makeCloth")){
System.out.println("对制作好的服装打包处理");
}
return invoke;
}
}
最后就是测试类进行测试:
package com.hxk.pattern.proxy.cglib_proxy.lx;
/**
* @author ***
* @create 2022-05-21 8:36
*/
public class Client {
public static void main(String[] args) {
NaiKeCloth cloth = new NaiKeCloth();
NaiKeCloth proxy = new ProxyFactory<NaiKeCloth>(cloth).getProxy();
proxy.makeCloth("短袖");
String brand = proxy.brand();
System.out.println(brand);
}
}
我们来看一下运行结果:
最后,若是有接口,则你可以使用JDK动态代理(看我主页静态代理和动态代理)带来实现代理;若是没有接口,则你就可以使用CGLIB进行代理。