您的位置:首页 > 编程语言 > Java开发

Java使用注解和动态代理实现方法调用时的日志记录示例

2017-10-27 10:09 1286 查看
1.定义一个注解:

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface LogTag {

    String level() default "info";

}

2.定义一个接口

public interface ITest {

    void excuteBusiness();

}

3.定义一个代理类

/**

* 代理类

* @author chenshuai

* @version 1.0

*

*/

public class ProxyBean implements InvocationHandler {

    private Object o;

    /**

     * @return the o

     */

    private Object getO() {

        return o;

    }

    /**

     * @param o the o to set

     */

    private void setO(Object o) {

        this.o = o;

    }

    /**

     * 创建代理

     * @param obj

     * @return

     */

    public static <T> T createProxy(T obj) {

        ProxyBean tem = new ProxyBean();

        tem.setO(obj);

        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), tem);

    }

    /*

     * (non-Javadoc)

     *

     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,

     * java.lang.reflect.Method, java.lang.Object[])

     */

    @Override

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //从实际的类对象中查找到所调用的具体方法,用来检测实际类的方法上的注解

        //否则需要把注解加载接口的方法上

        Method[] methods = o.getClass().getMethods();

        List<Class<?>> types = new ArrayList<Class<?>>();

        Method mm = null;

        //通过反射查找方法

        if (args == null || args.length == 0) {

            mm = o.getClass().getMethod(method.getName(), null);

        } else {

            for (Object oo : args) {

                types.add(oo.getClass());

            }

            mm = o.getClass().getMethod(method.getName(), (Class<?>[]) types.toArray());

        }

        System.out.println("代理启动");

        //检查注解类型

        Annotation[] annos = mm.getAnnotations();

        for (Annotation anno : annos) {

            if (anno instanceof LogTag) {

                LogTag tem = (LogTag) anno;

                System.out.println("探测到了LogTag注解,并且发现注解的level值为:" + tem.level());

            }

        }

        //调用具体的方法,执行业务逻辑

        method.invoke(o, args);

        System.out.println("代理结束");

        return null;

    }

}

4.定义一个入口测试类

public class TestBean implements ITest {

   

    @LogTag(level = "warn")

    public void excuteBusiness() {

        System.out.println("启动业务处理");

    }

    public static void main(String[] args) {

        ITest a = new TestBean();

        ITest proxy = ProxyBean.createProxy(a);

        proxy.excuteBusiness();

    }

}

运行结果



知识点:

1.Java动态代理:需要注意的是Java的动态代理要求被代理类必须继承自接口。

2.注解:注意@Retention和@Target两个注解的使用方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐