Java动态代理

一、什么是代理?

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;  
 }  

}

看到这里动态代理的方式大家应该了解了吧!还是那句话,如果我的文章对你撸码有帮助,请点一波关注,那里说的不对,请轻喷!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值