Java静态代理和动态代理的区别

我们来使用代理实现下简单的日志功能。

我们要在调用一个接口方法的时候给他记录日志的功能。

静态代理:

静态代理关键在代理对象和目标对象实现共同接口,并且代理对象持有目标对象的引用。

接口:

public interface DemoService {
    void doSomeThing(String name);
}

实现类:

class DemoServiceImpl implements DemoService {
    @Override
    public void doSomeThing(String name) {
        System.out.println("doing things"+name);
    }
}

静态代理类

public class ProxyDemoServiceImpl implements DemoService {

    private DemoService demoService;

    private ProxyDemoServiceImpl(DemoService demoService){
        super();
        this.demoService=demoService;
    }


    @Override
    public void doSomeThing(String name) {
        //日志增强
        System.out.println("log begin");
        demoService.doSomeThing(name);
        System.out.println("long end");
    }

  
  	//main
    public static void main(String[] args) {
        //原实现类
        DemoService service = new DemoServiceImpl();
        //静态代理对象
        service = new ProxyDemoServiceImpl(service);
        service.doSomeThing("单边李");
    }
}


		//结果
    log begin
		doing things单边李
		long end

静态代理的问题:项目中接口众多,方法也更多。这样一个一个增加,太麻烦了。

动态代理:

接口:

public interface DemoService {
    void doSomeThing(String name);
}

实现类:

public class DoTaiDemoServiceImpl implements DemoService {
    @Override
    public void doSomeThing(String name) {
        System.out.println("doing things"+name);
    }
}

关键的动态代理接口

在java动态代理机制中,有两个重要的类或接口:InvocationHandler(interface),Proxy(class)。这个接口和类是实现动态代理所必需用到的。

public class DoTaiDemoService implements InvocationHandler {

    //目标对象
    private Object target;

    public Object bind(Object object){
      	//传入目标对象
        this.target=object;
        //生成动态代理对象
        Object obj = Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
        return obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=null;
        System.out.println("method:"+method);
        System.out.println("args:"+ Arrays.toString(args));
      	//增强,日志
        System.out.println("log:begin");
        try {
          	//反射,动态调用方法
            result= method.invoke(this.target,args);
        }catch (Exception e){
            throw e;
        }
        System.out.println("log:end");
        return result;
    }

    public static void main(String[] args) {
      	//动态代理对象调用目标对象
      	//动态代理对象调用目标方法的时候,会执行代理对象的invoke方法,增加日志和try,并回调目标对象的方法
        DemoService service = (DemoService)new DoTaiDemoService().bind(new DoTaiDemoServiceImpl());
        service.doSomeThing("单边李");
    }
}

//结果:
args:[单边李]
log:begin
doing things单边李
log:end

和静态代理的区别:不用为每个接口创建代理类,只需要动态代理对象的bind方法,就可以获得织入增强后的对象。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值