动态代理的使用与各个参数的意义

动态代理:在不改变源码的情况下,对已有的方法进行增强(运行期增强),直接上代码,用法都在注释里,场景:定义一个演员类,演员可以做普通表演和危险表演,对演员类的方法进行增强

final ActerImpl acter = new ActerImpl();
    /**
     * 动态代理:
     *      作用:在不改变源码的情况下,对已有的方法进行增强
     *      特点:字节码随用随创建,随用随加载
     *      分类:基于接口的动态代理
     *           基于子类的动态代理
     *      基于接口的动态代理:
     *      要求:被代理类至少实现一个接口
     *      涉及类:proxy
     *      提供者:jdk
     *      创建对象的方法:newProxyInstance
     *   方法的参数:
  类加载器:ClassLoader,加载代理对象字节码,和被代理对象用一个类加载器
     *   字节码数组:Class[] 代理对象和被代理对象要具有相同的行为,实现相同接口
     *     如果被代理对象是一个实现类:对象.getClass().getinterfaces()
     *     如果被代理对象是一个接口:new Class[]{interface}
     *   增强方法的接口:InvocationHandler,如何增强,如何代理
     */
    Acter proxyActer =(Acter) Proxy.newProxyInstance(acter.getClass().getClassLoader(),
            acter.getClass().getInterfaces(),
            new InvocationHandler() {
                /**
                 * 作用:被代理对象执行每一个方法都会执行该方法,具有拦截功能
                 * @param proxy     代理对象的引用
                 * @param method    当前执行的方法
                 * @param args      执行当前方法所需要的参数
                 * @return
                 * @throws Throwable
                 */
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //获取参数
                    Float money = (Float) args[0];
                    Object rtValue = null;
                    if ("basicAct".equals(method.getName())){
                        if (money > 10000){
                            rtValue = method.invoke(acter,money*0.85f);//第一个参数:哪个对象的方法.第个二参数:执行方法所需要的参数
                        }
                    }
                    if ("dangerAct".equals(method.getName())){
                        if (money > 50000){
                            rtValue = method.invoke(acter,money*0.9f);//第一个参数:哪个对象的方法.第个二参数:执行方法所需要的参数
                        }
                    }
                    return rtValue;
                }
            });

    proxyActer.basicAct(20000f);
    proxyActer.dangerAct(55000f);
}
----------------------------------------------------------------------------
final ActerImpl acter = new ActerImpl();
/**
 * 动态代理:
 *      作用:在不改变源码的情况下,对已有的方法进行增强
 *      特点:字节码随用随创建,随用随加载
 *      分类:基于接口的动态代理
 *           基于子类的动态代理
 *      基于子类的动态代理:
 *              要求:被代理类不能是最终类
 *              涉及类:Enhancer
 *              提供者:cglib
 *              创建对象的方法:create
 *              方法的参数:
 *                      Class:加载代理对象字节码,使用的是被代理对象的字节码
 *                      Callback:增强方法的接口,和invocationhandler作用一样
 *                      allback是顶层接口,我们需要new MethodInterceptor
 */
ActerImpl cglibActer = (ActerImpl) Enhancer.create(acter.getClass(), new MethodInterceptor() {
    /**
     *代理对象的每个方法都会执行当前方法  拦截
     * @param proxy             代理类对象引用
     * @param method            当前执行的方法
     * @param args              执行当前方法需要的参数
     * @param methodProxy       执行当前方法的代理类对象
     * @return
     * @throws Throwable
     */
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        //获取参数
        Float money = (Float) args[0];
        Object rtValue = null;
        if ("basicAct".equals(method.getName())){
            if (money > 10000){
                rtValue = method.invoke(acter,money*0.85f);//第一个参数:哪个对象的方法.第个二参数:执行方法所需要的参数
            }
        }
        if ("dangerAct".equals(method.getName())){
            if (money > 50000){
                rtValue = method.invoke(acter,money*0.9f);//第一个参数:哪个对象的方法.第个二参数:执行方法所需要的参数
            }
        }
        return rtValue;
    }
});
cglibActer.basicAct(20000f);
cglibActer.dangerAct(60000f);

你可能感兴趣的:(底层原理,java,动态代理,proxyinstance,底层原理)