1、静态代理
在程序运行前,代理类的class文件已经生成(程序员自己创建)。
例子:
厂家货物交给经销商去卖。这里经销商是代理类,厂家具有进出货功能(被代理类)。代码实现:
创建一个接口:
public interface Shop {
/**
* 进货
* @return
*/
Integer purchase();
/**
* 卖货
* @return
*/
Integer sale();
}
被代理类,实现接口:
public class Shop4s implements Shop {
/**
* 进货量
*/
int purchase;
/**
* 售卖量
*/
int sale;
public Shop4s(int purchase,int sale) {
this.purchase = purchase;
this.sale = sale;
}
@Override
public Integer purchase() {
System.out.println("进货量:" + purchase);
return purchase;
}
@Override
public Integer sale() {
System.out.println("售卖量:" + sale);
return sale;
}
}
创建代理类,实现接口:
public class Shop4sProxy implements Shop{
/**
* 被代理对象
*/
Shop4s shop4s;
public Shop4sProxy(Shop shop) {
this.shop4s = (Shop4s) shop;
}
/**
* 代理进货方法
* @return
*/
@Override
public Integer purchase() {
return shop4s.purchase();
}
/**
* 代理售货方法
* @return
*/
@Override
public Integer sale() {
return shop4s.sale();
}
}
测试:
public static void main(String[] args) {
// 被代理对象
Shop beiJing4s = new Shop4s(10,2);
// 代理对象
Shop beiJing4sProxy = new Shop4sProxy(beiJing4s);
// 代理商(代理对象) 进货、卖货
beiJing4sProxy.purchase();
beiJing4sProxy.sale();
}
2、动态代理
代理类在程序运行时创建的代理方式被成为动态代理。Java动态代理是利用反射机制生成一个实现代理接口的代理类,在调用具体方法前调用InvokeHandler来处理。
2.1、jdk自带
定义一个接口:
public interface Shop {
/**
* 获取商品名称
*/
void getShopName();
}
创建被代理类:
public class Shop4s implements Shop{
/**
* 商品名
*/
String name;
public Shop4s(String name) {
this.name = name;
}
@Override
public void getShopName() {
System.out.println("该商品名是:" + name);
}
}
需要实现InvokeHandler接口:
public class CommonDynamicProxy<T> implements InvocationHandler {
// 通用的被代理对象
T commonCoverDynamicProxy;
public CommonDynamicProxy(T commonCoverDynamicProxy) {
this.commonCoverDynamicProxy = commonCoverDynamicProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk动态代理执行" + method.getName() + "方法");
method.invoke(commonCoverDynamicProxy, args);
return proxy;
}
}
测试:
public static void main(String[] args) {
// 被代理对象
Shop beiJing4s = new Shop4s("beiJing4s 路虎 E30");
// 创建一个与代理对象相关联的InvocationHandler
InvocationHandler shopDynamicProxy = new CommonDynamicProxy<Shop>(beiJing4s);
// 创建一个代理对象; 会执行 invoke()
Shop shop = (Shop) Proxy.newProxyInstance(
Shop.class.getClassLoader(),
new Class<?>[]{Shop.class},
shopDynamicProxy);
shop.getShopName();
}
2.2、cjlib
代码实现和jdk类似,不过需要引入jar包。代理类需要实现MethodInterceptor。
没有写这个实例,感兴趣的可以自行搜索。在这里推荐一篇文章:https://blog.youkuaiyun.com/zhangyong01245/article/details/90644933
2.3、jdk与cjlib区别
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP(<aop:aspectj-autoproxy proxy-target-class="true"/>)。
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换。
4、对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建代理对象,所以比较适合采用CGLib动态代理,反正,则比较适用JDK动态代理。
参考
https://blog.youkuaiyun.com/qq_40244666/article/details/89710673
本文详细解析了Java中静态代理和动态代理的概念及其实现方式,包括如何通过接口和代理类进行方法调用的预处理,同时对比了JDK动态代理和CGLIB的优缺点及适用场景。
168万+

被折叠的 条评论
为什么被折叠?



