码迷,mamicode.com
首页 > 编程语言 > 详细

【Java】代处理?代理模式 - 静态代理,动态代理

时间:2015-09-02 00:19:00      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:

>不用代理

有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码。

 

这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果。(至于为什么不直接用+号运算,见【Java】Float计算不准确

package com.nicchagil.study.java.demo.No09代理.No01不用代理;

import java.math.BigDecimal;

public class FloatCalculator {

    public float add(float a, float b) {
        
        BigDecimal b1 = new BigDecimal(a + "");
        BigDecimal b2 = new BigDecimal(b + "");
        float f = b1.add(b2).floatValue();
        
        return f;
        
    }
}

 

我想在它运行前后打印,最直接的方式就是调用时打印了

package com.nicchagil.study.java.demo.No09代理.No01不用代理;

public class Call {

    public static void main(String[] args) {
        float f1 = 1f;
        float f2 = 1f;
        
        System.out.println("f1 -> " + f1 + ", f2 -> " + f2);
        float result = new FloatCalculator().add(f1, f2);
        System.out.println("result -> " + result);
    }
}

 

看到这日志,我很欣慰!

f1 -> 1.0, f2 -> 1.0
result -> 2.0

 

>静态代理

随着项目变大,调用此方法的地方变得越来越多,如果有10个调用的地方,我岂不是要写100次打印的方法。

这时,静态代理的方式能帮助我们。

 

定义个接口

package com.nicchagil.study.java.demo.No09代理.No02静态代理;


public interface ICalculator {
    
    /**
     * <p>add</p>
     */
    public float add(float a, float b);
    
}

 

真实业务类

package com.nicchagil.study.java.demo.No09代理.No02静态代理;

import java.math.BigDecimal;

public class FloatCalculator implements ICalculator {

    @Override
    public float add(float a, float b) {
        
        BigDecimal b1 = new BigDecimal(a + "");
        BigDecimal b2 = new BigDecimal(b + "");
        float f = b1.add(b2).floatValue();
        
        return f;
        
    }
    
}

 

代理类,这个类中,处理执行实际业务,还一并捆绑打印日志的任务

package com.nicchagil.study.java.demo.No09代理.No02静态代理;



public class FloatCalculatorProxy implements ICalculator {
    
    ICalculator c = null;
    
    /**
     * 构造方法
     * @param c    需被代理的对象
     */
    public FloatCalculatorProxy(ICalculator c) {
        super();
        this.c = c;
    }

    @Override
    public float add(float f1, float f2) {
        System.out.println("f1 -> " + f1 + ", f2 -> " + f2);
        
        float result = this.c.add(f1, f2);
        
        System.out.println("result -> " + result);
        return result;
    }
    
}

 

然后,我们调用时,只需调用代理类,不仅计算得结果,日志也乖乖地出来了

package com.nicchagil.study.java.demo.No09代理.No02静态代理;

public class Call {
    
    public static void main(String[] args) {
        System.out.println("代理的对象:");
        ICalculator c2 = new FloatCalculatorProxy(new FloatCalculator());
        c2.add(1f, 1f);
    }

}

 

看到日志,我很镇静

代理的对象:
f1 -> 1.0, f2 -> 1.0
result -> 2.0

 

>动态代理

如果现在不仅FloatCalculator这个类需要打印日志,还有其他各种类也需要打印日志,那么我们岂不是要写好多个代理类了?

这时候,Java API拍案而起,提出动态代理。通过反射机制为我们实现动态代理。

 

接口类(ICalculator)、真实业务类(FloatCalculator)如同静态代理,不再重复

 

调用处理类

package com.nicchagil.study.java.demo.No09代理.No03动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicProxyHandler implements InvocationHandler {
    
    private Object proxied = null;
    
    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("Clazz    -> " + proxy.getClass());
        System.out.println("method    -> " + method);
        for (int i = 0; i < args.length; i++) {
            System.out.println("args[" + i + "]    -> " + args[i]);
        }
        
        Object result = method.invoke(proxied, args);
        
        System.out.println("result    -> " + (result != null ? result.toString() : ""));
        return result;
    }

}

 

调用类

package com.nicchagil.study.java.demo.No09代理.No03动态代理;

import java.lang.reflect.Proxy;

import com.nicchagil.study.java.demo.No09代理.No02静态代理.FloatCalculator;
import com.nicchagil.study.java.demo.No09代理.No02静态代理.ICalculator;

public class Call {
    
    public static void main(String[] args) {
        /* 代理的对象 */
        System.out.println("代理的对象:");
        ICalculator c2 = (ICalculator)Proxy.newProxyInstance(ICalculator.class.getClassLoader(), 
                new Class[] {ICalculator.class}, new DynamicProxyHandler(new FloatCalculator()));
        c2.add(1f, 1f);
    }

}

 

日志

代理的对象:
Clazz    -> class $Proxy0
method    -> public abstract float com.nicchagil.study.java.demo.No09代理.No02静态代理.ICalculator.add(float,float)
args[0]    -> 1.0
args[1]    -> 1.0
result    -> 2.0

 

暂时完毕。

 

【Java】代处理?代理模式 - 静态代理,动态代理

标签:

原文地址:http://www.cnblogs.com/nick-huang/p/4777290.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!