JDK和CGLib动态代理怎么实现
导读:本文共3697.5字符,通常情况下阅读需要12分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 前言:动态代理是一种常用的设计模式,广泛应用于框架中,Spring框架的AOP特性就是应用动态代理实现的,想要理解AOP的实现原理我们就必须先理解动态代理。什么是代理模式代理模式是GOF23设计模式之一,代理模式中存在代理者和被代理者,代理者和被代理者都具有相同的功能,并且代理者执行功能时会附加一些额外的操作如:手机工厂和代理商都具有卖东西的功能,手机代理商除了... ...
目录
(为您整理了一些要点),点击可以直达。- (6):2)项目的扩展和维护比较方便
- (10):2)代理者包含了一个被代理者的对象
- (12):/**
- (13):*卖手机
- (14):*/
- (18):/**
- (19):*小米手机工厂
- (20):*/
- (26):/**
- (27):*小米代理商
- (28):*/
- (30)://被代理者,工厂对象
- (32)://通过构造方法传入被代理者
- (38)://调用被代理者的方法
- (46)://创建被代理者
- (50)://创建代理者
- (52)://调用卖手机
- (60):2)不需要依赖某个具体业务
- (66):1)代理类需要实现InvocationHandler接
- (67):2)实现invoke方法
- (69):/**
- (70):*动态代理
- (71):*/
- (73)://被代理者对象
- (75):/**
- (76):*创建代理对象
- (77):* @param object被代理者
- (78):* @return代理者
- (79):*/
- (85):/**
- (86):*调用被代理者方法,同时添加新功能
- (87):*/
- (90)://调用被代理者的方法
- (99)://创建动态代理对象
- (101)://被代理对象
- (103)://创建代理对象
- (109):/**
- (110):* CGLib动态代理
- (111):*
- (112):*/
- (114):/**
- (115):*返回代理对象
- (116):* @param object被代理对象
- (117):* @return代理对象
- (118):*/
- (120)://创建加强器
- (122)://设置被代理对象的类为父类
- (124)://设置代理对象的回调
- (130)://调用父类对象的方法
前言:动态代理是一种常用的设计模式,广泛应用于框架中,Spring框架的AOP特性就是应用动态代理实现的,想要理解AOP的实现原理我们就必须先理解动态代理。
什么是代理模式
代理模式是GOF23设计模式之一,代理模式中存在代理者和被代理者,代理者和被代理者都具有相同的功能,并且代理者执行功能时会附加一些额外的操作
如:手机工厂和代理商都具有卖东西的功能,手机代理商除了帮工厂卖手机外,还能在卖手机前打广告推销,卖手机后还可以进行售后服务。
代理模式的优点:
1)符合开闭原则,不用修改被代理者任何的代码,就能扩展新的功能
2)项目的扩展和维护比较方便
代理模式分为:静态代理和动态代理
静态代理
什么是静态代理
1)代理者和被代理者都实现了相同的接口(或继承相同的父类)
2)代理者包含了一个被代理者的对象
3)调用功能时,代理者会调用被代理者的功能,同时附加新的操作
/**
*卖手机
*/
public interface SellMobilePhone {
void sellMobilePhone();
}
/**
*小米手机工厂
*/
public class MiPhoneFactory implements SellMobilePhone{
public void sellMobilePhone() {
System.out.println("生产了小米9手机,卖出去!!");
}
}
/**
*小米代理商
*/
public class MiPhoneAgent implements SellMobilePhone {
//被代理者,工厂对象
private SellMobilePhone factory;
//通过构造方法传入被代理者
public MiPhoneAgent(SellMobilePhone factory){
this.factory = factory;
}
public void sellMobilePhone() {
System.out.println("打广告,做活动~~~~~~~~~~~~~~~~~");
//调用被代理者的方法
factory.sellMobilePhone();
System.out.println("做售后,做推销~~~~~~~~~~~~~~~~~");
}
}
public class TestStaticProxy {
@Test
public void testProxy(){
//创建被代理者
SellMobilePhone factory = new MiPhoneFactory();
factory.sellMobilePhone();
System.out.println("---------------------------------------");
//创建代理者
SellMobilePhone agent = new MiPhoneAgent(factory);
//调用卖手机
agent.sellMobilePhone();
}
}
静态代理的问题:
静态代理只能适合一种业务,如果有新的业务,就必须创建新的接口和新的代理,如添加卖电脑的接口和电脑工厂,就要创建新的电脑代理类。
动态代理
动态代理的特点:
1)在不修改原有类的基础上,为原来类添加新的功能
2)不需要依赖某个具体业务
动态代理分为:JDK动态代理和CGLib动态代理
区别是:
JDK动态代理的被代理者必须实现任意接口
CGLib动态代理不用实现接口,是通过继承实现的
JDK动态代理
实现步骤:
1)代理类需要实现InvocationHandler接口
2)实现invoke方法
3)通过Proxy类的newProxyInstance方法来创建代理对象
/**
*动态代理
*/
public class SalesAgent implements InvocationHandler{
//被代理者对象
private Object object;
/**
*创建代理对象
* @param object被代理者
* @return代理者
*/
public Object createProxy(Object object){
this.object = object;
//Proxy.newProxyInstance创建动态代理的对象,传入被代理对象的类加载器,接口,InvocationHandler对象
return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
}
/**
*调用被代理者方法,同时添加新功能
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("销售之前,打广告~~~~~~");
//调用被代理者的方法
Object result = method.invoke(object,args);
System.out.println("销售之后,做售后~~~~~~");
return result;
}
}
public class TestInvocationHandler {
@Test
public void testInvocation(){
//创建动态代理对象
SalesAgent agent = new SalesAgent();
//被代理对象
SellMobilePhone sellMobilePhone = new MiPhoneFactory();
//创建代理对象
SellMobilePhone phoneProxy = (SellMobilePhone) agent.createProxy(sellMobilePhone);
phoneProxy.sellMobilePhone();
}
}
CGLib动态代理
特点:通过继承实现,被代理者必须能被继承,通过被代理类创建子类,子类就是父类的代理。
/**
* CGLib动态代理
*
*/
public class CGLibProxy implements MethodInterceptor {
/**
*返回代理对象
* @param object被代理对象
* @return代理对象
*/
public Object createProxy(Object object){
//创建加强器
Enhancer eh = new Enhancer();
//设置被代理对象的类为父类
eh.setSuperclass(object.getClass());
//设置代理对象的回调
eh.setCallback(this);
return eh.create();
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("售前~~~~~~CGLIB");
//调用父类对象的方法
Object res = proxy.invokeSuper(obj, args);
System.out.println("售后~~~~~~CGLIB");
return res;
}
}
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
JDK和CGLib动态代理怎么实现的详细内容,希望对您有所帮助,信息来源于网络。