动态代理

Java动态代理实践
本文介绍Java动态代理原理及实现,通过实例演示如何使用反射机制在方法前后打印日志,实现对方法的拦截和控制。

当我们需要在一个方法的前后打印日志的时候,我们通常想到的办法就是在调用这个方法的前后进行打印,今天我们就来看一下java里面的反射机制如何在方法前后进行打印.

首先,我们介绍一下代理(Proxy):对被代理对象(xxx)所有的方法进行"拦截和控制".

下面,我们通过一段简短的代码认识一下动态代理:

关于类加载器的作用:

1.将硬盘上的class文件加载到内存的方法区中进行存储;

2.当class文件加载完成之后,类加载器会在堆区中创建一个用于描述该方法区中代码结构的一个Class对象

下面来看整个动态代理的实现:

public interface SuperStar {
    void sing( int money );

    void liveShow( int money );

    void sleep();
}
public class XXX implements SuperStar {

    @Override
    public void sing( int money ) {
        System.out.println( "某明星准备唱歌去!" );
        System.out.println( "赚了: " + money + "块钱" );
    }

    @Override
    public void liveShow( int money ) {
        System.out.println( "演唱<<Running Man>>!" );
        System.out.println( "获得了 : " + money + "块钱" );
    }

    @Override
    public void sleep() {
        System.out.println( "某明星和某富豪...Zzzz~~" );
    }

}
public class SuperStarDemo {
    @Test
    public void demo01() {
        // 1. 创建一个实例对象
        XXX xxx = new XXX();

        // 2.对象的方法
        xxx.sing( 5 );
        xxx.liveShow( 10 );
        xxx.sleep();
    }

    @Test
    public void demo02() {
        // 1. 创建一个实例对象
        final XXX xxx = new XXX();

        // 到底执行什么方法,取决于真实类
        // 代理proxy :对被代理对象所有的方法进行"拦截和控制".
        // 引导类/根类加载器,扩展类加载器,应用类加载器
        /************** 创建动态代理的代码start ******************/
        ClassLoader loader = SuperStarDemo.class.getClassLoader();
        // ClassLoader loader = xxx.getClass()
        // .getClassLoader();
        System.out.println( loader );
        Class<?>[] interfaces = xxx.getClass()
                                   .getInterfaces();
        // new InvocationHandler(){} 匿名接口实现类对象
        SuperStar proxy = (SuperStar) Proxy.newProxyInstance( loader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable {
                // 打印方法名称和参数
                // System.out.println(method.getName());
                // System.out.println(Arrays.toString(args));

                // 打印代理类
                System.out.println( proxy.getClass() ); // proxy.toString();

                // Object proxy代理类本身
                // Method 调用当前执行的方法
                // Object[] args 当前执行方法的实际参数
                // return method.invoke(目标类实例, args);

                // 1. 获取当前方法
                String methodName = method.getName();

                // 2. 方法判断
                if ( "sing".equals( methodName ) ) {
                    // 获取参数
                    int money = (int) args[ 0 ];
                    // 判断
                    if ( money < 10000 ) {
                        System.out.println( "钱太少了不干..." );
                        return null; // 跳出
                    }
                    // 打印
                    System.out.println( "代理分成: " + money * 0.3 );
                    // 执行方法
                    return method.invoke( xxx, (int) ( money * 0.7 ) );
                } else if ( "liveShow".equals( methodName ) ) {
                    // 获取参数
                    int money = (int) args[ 0 ];
                    // 判断
                    if ( money < 100000 ) {
                        System.out.println( "hi, How old are you. money too shao le..." );
                        return null; // 跳出
                    }
                    // 打印
                    System.out.println( "代理分成: " + money * 0.3 );
                    // 执行方法并跳出
                    return method.invoke( xxx, (int) ( money * 0.7 ) );
                } else {
                    return method.invoke( xxx, args );
                }
            }
        } );

        /************** 创建动态代理的代码end ******************/
        // 2. 应该调用代理类对象的方法
        proxy.sing( 10000 );
        proxy.liveShow( 100000 );
        proxy.sleep();
    }
}

以上,是动态代理的简单实现.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值