基于接口和子类的动态代理详解

动态代理详解(基于接口和子类)

基于接口的动态代理使用步骤:

1.创建被代理对象,并创建函数。(例如厂家)
2.创建代理对象(接口),并定义方法(被代理对象中的方法)。(经销商)
3.让被代理对象实现代理对象中的方法。
4.创建主函数,使用代理动态代理并测试。
	1.创建被代理的对象,并声明为最终变量。
	2.调用Proxy的newProxyInstance方法,对被代理的对象方法进行增强,并将返回值传递给代理对象。
	3.代理对象调用方法,进行操作。
		public static void main(String[] args) {
    		final Producer producer = new Producer();
			IProduct proxyProducer = (IProduct) Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(), new InvocationHandler() {
            /**
             * 作用:执行被代理对象的任何接口方法都会经过该方法
             * 方法参数含义:
             * @param proxy     代理对象的引用
             * @param method    当前执行的方法
             * @param args      当前执行方法所需的参数
             * @return          和被代理对象方法有相同的返回值
             * @throws Throwable
             */
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //提供增强的代码
                Object returnValue= null;
                //1.获取方法执行的参数
                Float money = (Float) args[0];
                //2.判断当前方法是不是销售
                if ("saleProduct".equals(method.getName())){
                    returnValue = method.invoke(producer,money*0.8f);
                }
                return returnValue;
            }
        });
        proxyProducer.saleProduct(10000f);
    }

分析:

动态代理:
        特点:字节码随用随创建,随用随加载
        作用:不修改源码的基础上,对源码进行增强
        分类:
            基于接口的动态代理
            基于子类的动态代理
        基于接口的动态代理:
            涉及的类:Proxy
            提供者:JDK官方
        如何创建代理对象:
            使用Proxy类中的newProxyInstance方法
        创建代理对象要求:
            被代理的类最少实现一个接口,如果没有则不能使用
        newProxyInstance方法的参数:
            ClassLoader:类加载器
                它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法。
            Class[]:字节码数组
                它是用于让代理对象和被代理对象有相同方法。固定写法。
            InvocationHandler:用于提供增强的代码
                它是让我们写如何代理。我们一般都是写一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。此接口的实现类都是谁用谁写。

基于子类的动态代理使用步骤:

1.创建被代理对象,并实现方法。
2.在pom文件中导入jar包。(cglib)
3.创建主函数,使用动态代理并测试。
	1.创建被代理类,并声明为最终类。
	2.使用Enhancer类的creat方法,进行方法增强,并将返回值交给被代理对象。(此对象为新建的)
	3.调用代理对象进行方法测试。
		public static void main(String[] args) {
	        final Producer producer = new Producer();
	        Producer cglibProducer=(Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
	            /**
	             * 执行被代理对象的任何方法都会经过该方法
	             * @param proxy
	             * @param method
	             * @param args
	             *      以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
	             * @param methodProxy:当前执行方法的代理对象
	             * @return
	             * @throws Throwable
	             */
	            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
	                Object returnValue= null;
	                //1.获取方法执行的参数
	                Float money = (Float) args[0];
	                //2.判断当前方法是不是销售
	                if ("saleProduct".equals(method.getName())){
	                    returnValue = method.invoke(producer,money*0.8f);
	                }
	                return returnValue;
	            }
	
	        });
	        cglibProducer.saleProduct(18000f);
	    }

分析:

动态代理:
        基于子类的动态代理:
            涉及的类:Enhancer
            提供者:第三方cglib
        如何创建代理对象:
            使用Enhancer类中的creat方法
        创建代理对象要求:
            被代理的类不能是最终类
        creat方法的参数:
            Class:字节码
                它是用于指定被代理对象字节码的。

            callback:用于提供增强的代码
                它是让我们写如何代理。我们一般都是写一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。此接口的实现类都是谁用谁写。
            我们一般写的都是该接口的子接口实现类:MethodInterceptor
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值