一、什么是代理?
1.举一个例子:租房。
这里就引出了三个角色,需要租房的人,中介,房东
租房的人
中介:代理者(Subject)
房东:被代理的对象(RealSubject)
房东把房子交给中介处理,中介给予房东他们谈好的价格,之后中介就对房屋有了代理权,至于再租看房的人中间需要的额外费用就有中介来收取了!
2.看到这里应该能明白Java的代理模式能解觉什么问题了吗?
比如我们有这样一个接口:
package com.gj.service;
public interface Subject {
//房屋出售
//housePrice房屋价格
//serverPrice服务费
public int saleHouse(int housePrice,int serverPrice);
}
接着我们去实现它:
package com.gj.service;
public class RealSunject implements Subject {
@Override
public int saleHouse(int housePrice,int serverPrice) {
return housePrice+serverPrice;
}
}
package com.gj.service;
public class HaiDian implements Subject{
@Override
public int saleHouse(int housePrice, int serverPrice) {
//海淀区
return housePrice+serverPrice;
}
}
package com.gj.service;
//我们去用代理的思想解决
public class HaiDianSaleHouse implements Subject{
Subject subject;
public HaiDianSaleHouse (Subject subject) {
this.subject=subject;
}
@Override
public int saleHouse(int housePrice, int serverPrice) {
//海淀区
housePrice=8000;
serverPrice=1500;
return subject.saleHouse(housePrice, serverPrice);
}
}
//同时这里会牵扯到多态的机制,后续会讲解
那么每个区的房价和服务费是不一样的,这个问题我们怎么解决呢!这就需要用到动态代理了,我们修改一下上面的例子,先看,一会在解释
package com.gj.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SaleProxy {
private SaleProxy (){};
public static Object getProxy(Object subject){
/**jdk自带的动态代理Proxy.newProxyInstance(
* 代理对象的类加载器,
* 代理对象的接口,
* InvocationHandler(Object proxy, Method method, Object[] args)
* 第一个参数为被代理对象
* 第二个参数是被代理对象的方法
* 第三个参数为方法需要的参数
* //利用反射(之前已经介绍过了!)机制去调用被代理对象的方法
* )
*
*/
Proxy.newProxyInstance(
subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object subject, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
return method.invoke(subject, args);
}
});
return subject;
}
}
这里选择静态方法是一位static修饰的方法是属于类级别的,不需要创建类的实例就可以调用
3.看到这里应该明白什么是动态代理了吧!那么我们把思维放到我们日常撸码的业务上,动态代理解决的是什么问题呢?
比如,权限控制,日志收集,事物处理,等等
那么再来看看jdk原生的动态代理有什么缺点:
1.必须实现接口,如果你需要代理的类没有实现接口那么jdk的动态代理就拉闸了,这时需要用到Cglib这个
第三方提供的动态代理了。
这里插一句:spring的aop集成了这俩种代理方式通过修改属性去让spring去使用哪种代理方式,当然spring会自动处理两种代理方式的选择
2.对于不同的业务我们需要创建不同的代理,比如,权限控制,日志收集,事物处理,等等
4.Cglib的动态代理
“`
package com.gj.service;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibSaleHouse implements MethodInterceptor{
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
//设置需要创建子类的类
enhancer.setSuperclass(clazz);
//设置回调函数
enhancer.setCallback(this);
//通过字节码技术动态创建子类实例
return enhancer.create();
}
//实现MethodInterceptor接口方法
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
//通过代理类调用父类中的方法
Object result = proxy.invokeSuper(obj, args);
return result;
}
}
“
看到这里动态代理的方式大家应该了解了吧!还是那句话,如果我的文章对你撸码有帮助,请点一波关注,那里说的不对,请轻喷!