spring第三天动态代理

25 篇文章 0 订阅

动态代理

动态代理,是在不改变源码的基础上,对已有的代码增强(它是aop思想的实现技术)

动态代理分类

1.基于接口的动态代理

要求:被代理类最少实现一个接口
         *                 提供者jdk官网
         *                 创建代理对象的方法:proxy.newproxyinstance(classloader,calss[],invocationhandler)
         *                 参数的含义:
         *                     classloader:类加载器,和被代理对象使用相同的类加载器,一般都是固定写法
         *                     class[]:字节码数组,被代理类实现的接口。(要求代理对象和被代理对象具有相同的行为)。一般都是固定写法
         *                     invocationhandler 它是一个接口,就是我们用于提供增强代码的,我们一般都    是写一个该接口的实现类,实现类可以是一个匿名内部类    
         *                         它的含义就是如何代理。此处的代码只能是谁用谁提供
         *                         策略模式:
         *                             使用要求:数据已经有了
         *                                 目的明确
         *                                 达成目标的过程就是策略
         *                         在dbutils中的resultsethandler就是策略模式的具体应用。
         * 

示例:

cn.pro.proxy.IActor

package cn.pro.proxy;

public interface IActor {
	public void basicAct(float money);
	public void dangerAct(float money);
}

cn.pro.proxy.Actor

package cn.pro.proxy;

public class Actor implements IActor{
	public void basicAct(float money){
		System.out.println("拿到钱,开始基本的表演" + money);
		
	}
	public void dangerAct(float money){
		System.out.println("拿到钱,开始危险的表演" + money);
		
	}
}

 cn.pro.proxy.Client

package cn.pro.proxy;

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

public class Client {

	/**
	 * 
	 * 模拟一个剧组
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final Actor ac = new Actor();	
		
		
		IActor proxyactor = (IActor) Proxy.newProxyInstance(Actor.class.getClassLoader(), 
				Actor.class.getInterfaces(),
				new InvocationHandler() {
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				
				/*被代理对象的任何方法都会经过该方法,该方法有拦截的功能
				 * 方法的参数  
				 * 	 Object proxy, 代理对象的引用,不一定每次都会有
				 * 		
				 *	 Method method,当前执行的方法
				 * 
				 *	 Object[] args  当前执行方法所需的参数 
				 *返回值  当前执行方法的返回值 
				 * 
				 * 
				 * 
				 * 
				 * */
						Object rtValue =null;
						//1取出执行方法中的参数 
						float money = (Float) args[0];
						//2判断当前执行的是什么方法。
						//如果多于一万 则开始普通的表演 
						if("basicAct".equals(method.getName())){
							if (money >10000){
								//执行方法
								rtValue = method.invoke(ac, money);
							}
							}
				
				//如果多于5万,则开始危险的表演
						if("dangerAct".equals(method.getName())){
							if(money>50000){
								rtValue = method.invoke(ac, money);
							}
							
							
						}
				
				
				return rtValue;
				}
			} );
		
		
		proxyactor.basicAct(10000f);
		proxyactor.dangerAct(50000f);
		proxyactor.basicAct(20000f);
		proxyactor.dangerAct(60000f);
	}

	

}

此动态代理,对参数进行了限定,如果一般表演的费用没有10000 或者危险表演的费用没有60000则不执行方法,没有表演。

总结:动态代理是对参数进行策略,结合if语句,如果某方法的某参数等于或大于某值则。。。。

基于子类的动态 代理

         *     要求:被代理类不能是最终类。不能被final修饰
         *         提供者是第三方CGLIB
         *         涉及的类:enhancer
         *         创建代理对象的方法:create(Class,callback)
         *         参数的含义
         *             class:被代理对象的字节码
         *             callback:如何代理,它和invocationhandler作用是一样的,它也是一个接口,我们一般使用该接口的子接口,
         *             它的子接口是methodinterceptor
         *                 在使用时,也是创建该接口的匿名内部类

导包:

cglib.Actor

package cglib;

public class Actor {
	public void basicAct(float money){
		System.out.println("拿到钱,开始基本的表演" + money);
		
	}
	public void dangerAct(float money){
		System.out.println("拿到钱,开始危险的表演" + money);
		
	}
}

cglib.Client

package cglib;

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

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class Client {

	/**
	 * 
	 * 模拟一个剧组
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final Actor ac = new Actor();
		/*
		 * 
		 * 基于子类的动态代理
		 * 	要求:被代理类不能是最终类。不能被final修饰
		 * 		提供者是第三方CGLIB
		 * 		涉及的类:enhancer
		 * 		创建代理对象的方法:create(Class,callback)
		 * 		参数的含义
		 * 			class:被代理对象的字节码
		 * 			callback:如何代理,它和invocationhandler作用是一样的,它也是一个接口,我们一般使用该接口的子接口,
		 * 			它的子接口是methodinterceptor
		 * 				在使用时,也是创建该接口的匿名内部类
		 *  
		 * 
		 * */			
		
		Actor cglibactor = (Actor) Enhancer.create(Actor.class, new MethodInterceptor() {
			
			@Override
			public Object intercept(Object proxy, Method method, Object[] args,
					MethodProxy methodproxy
					) throws Throwable {
				
				
				/*执行被代理对象的任何方法都会进过该方法,它和基于接口动态代理的invoke方法作用是一模一样的
				 * 
				 * 方法的参数  
				 * 	前面三个参数与基于接口的动态代理参数一样   
				 * 	MethodProxy arg3 :当前执行方法的代理对象,一般不用   
				 * 
				 * */
				// TODO Auto-generated method stub
				Object rtValue =null;
				//1取出执行方法中的参数 
				float money = (Float) args[0];
				//2判断当前执行的是什么方法。
				//如果多于一万 则开始普通的表演 
				if("basicAct".equals(method.getName())){
					if (money >10000){
						//执行方法
						rtValue = method.invoke(ac, money);
					}
					}
		
		//如果多于5万,则开始危险的表演
				if("dangerAct".equals(method.getName())){
					if(money>50000){
						rtValue = method.invoke(ac, money);
					}
					
					
				}
		
		
		return rtValue;
			}
		});
		
		cglibactor.basicAct(10000f);
		cglibactor.dangerAct(60000f);

	}

	

}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值