zoukankan      html  css  js  c++  java
  • 动态代理

      面向接口的jdk动态代理(spring默认代理)

    package com.yc.advice;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Date;
    
    public class  LogAdvice  implements InvocationHandler {
    	//代理模式中一定要有目标类的引用
    	private Object tagetObject;  //注意这个就是目标类的应用
    	
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		//调用目标的相应方法
    		Object returnValue=method.invoke(tagetObject, args);
    		String methodName=method.getName();
    		if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){
    			log(method,args,tagetObject);
    		}
    		return returnValue;
    	}
    	//创建一个方法来完毕创建代理对象
    	
    	public Object createInstance(Object tagetObject){
    		this.tagetObject=tagetObject;
    		//生成一个代理对象
    		//生成一个代理对象,这个代理对象使依据目标对象的接口生成的
    		return Proxy.newProxyInstance(tagetObject.getClass().getClassLoader(),tagetObject.getClass().getInterfaces() , this);
    		//在client我们调用createInstance()得到一个代理对象,在调用这个代理对象的方法->它就会自己主动的回调(由于this)invoke
    		//全部在invoke里面写入你要增强的方法
    		
    	}
    	private void log(Method method, Object[] args, Object tagetObject2){
    		System.out.println("********************");
    		System.out.println("日志检查"+new Date());
    		System.out.println("********************");
    	}
    	
    }
    

    package com.yc.advice;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    //在这个类使一个且面类。完毕的功能使向目标类的目标方法增加功能(增强)
    public class RightAdvice  implements InvocationHandler{
    	//代理模式中一定要有目标类的引用
    	private Object tagetObject;  //注意这个就是目标类的应用
    	
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		String methodName=method.getName();
    		if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){
    			check();
    		}
    	
    		//调用目标的相应方法
    		Object returnValue=method.invoke(tagetObject, args);
    		return returnValue;
    	}
    	//创建一个方法来完毕创建代理对象
    	public Object createInstance(Object tagetObject){
    		this.tagetObject=tagetObject;
    		//生成一个代理对象
    		//生成一个代理对象,这个代理对象使依据目标对象的接口生成的
    		return Proxy.newProxyInstance(tagetObject.getClass().getClassLoader(),tagetObject.getClass().getInterfaces() , this);
    		//在client我们调用createInstance()得到一个代理对象,在调用这个代理对象的方法->它就会自己主动的回调(由于this)invoke
    		//全部在invoke里面写入你要增强的方法
    		
    	}
    	private void check(){
    		System.out.println("********************");
    		System.out.println("权限检查");
    		System.out.println("********************");
    	}
    
    }
    


    package com.yc.biz;
    
    public interface ProductBiz {
    	public void addProduct();
    	public void delProduct();
    	public void updateProduct();
    	public void findProduct();
    	
    }
    

    package com.yc.biz;
    //真是主题
    public class ProductBizImpl implements ProductBiz {
    
    	@Override
    	public void addProduct() {
    		System.out.println("************************");
    		System.out.println("加入产品");
    		System.out.println("*************************");
    	}
    
    	@Override
    	public void delProduct() {
    		System.out.println("************************");
    		System.out.println("删除产品");
    		System.out.println("*************************");
    		
    	}
    
    	@Override
    	public void updateProduct() {
    		System.out.println("************************");
    		System.out.println("更新产品");
    		System.out.println("*************************");
    		
    	}
    
    	@Override
    	public void findProduct() {
    		System.out.println("************************");
    		System.out.println("查找产品");
    		System.out.println("*************************");
    		
    	}
    
    }
    

    package com.yc.biz;
    
    import com.yc.advice.LogAdvice;
    import com.yc.advice.RightAdvice;
    
    public class Test {
    
    	public static void main(String[] args) {
    			RightAdvice ra=new RightAdvice();
    			LogAdvice la=new LogAdvice();
    			ProductBiz pb=new ProductBizImpl();
    			ProductBiz productProxy=(ProductBiz) ra.createInstance(la.createInstance(pb));
    			productProxy.addProduct();
    	}
    
    }
    
    
    
    

    另一种是面向继承的cglib动态代理

    首先要导入一个包cglib-nodep-2.1_3.jar

    还是上面的样例,可是差别在于增强类的写法上有一点不同,大家看一下

    package com.yc.advice;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Date;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class  LogAdvice  implements MethodInterceptor {
    	//代理模式中一定要有目标类的引用
    	private Object tagetObject;  //注意这个就是目标类的应用
    	
    	//创建一个方法来完毕创建代理对象
    	
    	public Object createInstance(Object tagetObject){
    		this.tagetObject=tagetObject;
    		Enhancer enhancer=new Enhancer();
    		enhancer.setSuperclass(tagetObject.getClass());
    		enhancer.setCallback(this);
    		return enhancer.create();
    		
    	}
    	private void log(Method method, Object[] args, Object tagetObject2){
    		System.out.println("********************");
    		System.out.println("日志检查"+new Date());
    		System.out.println("********************");
    	}
    	@Override
    	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable {
    		//调用目标的相应方法
    				Object returnValue=method.invoke(tagetObject, args);
    				String methodName=method.getName();
    				if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){
    					log(method,args,tagetObject);
    				}
    				return returnValue;
    	}
    	
    }
    

    package com.yc.advice;
    
    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 RightAdvice  implements MethodInterceptor{
    	//代理模式中一定要有目标类的引用
    	private Object tagetObject;  //注意这个就是目标类的应用
    	
    	
    	//创建一个方法来完毕创建代理对象
    	public Object createInstance(Object tagetObject){
    		this.tagetObject=tagetObject;
    		Enhancer enhancer=new Enhancer();
    		enhancer.setSuperclass(tagetObject.getClass().getSuperclass());
    		enhancer.setCallback(this);
    		return enhancer.create();
    		
    	}
    	private void check(){
    		System.out.println("********************");
    		System.out.println("权限检查");
    		System.out.println("********************");
    	}
    	@Override
    	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
    		String methodName=method.getName();
    		if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){
    			check();
    		}
    	
    		//调用目标的相应方法
    		Object returnValue=method.invoke(tagetObject, args);
    		return returnValue;
    	}
    
    }
    




      想了想静态代理也贴上来了。我认为静态代理便于理解,更直观

        和上面不同的是将增强类LogAdvice和RightAdvice两个类替换成了ProductBIzLogProxy和ProductBIzRightProxy两个类

    package com.yc.biz;
    
    import java.util.Date;
    
    public class ProductBIzLogProxy implements ProductBiz{
    	private ProductBiz productBiz;
    	public  ProductBIzLogProxy(ProductBiz productBiz) {
    		// TODO Auto-generated constructor stub
    		this.productBiz=productBiz;
    	}
    	@Override
    	public void addProduct() {
    		// TODO Auto-generated method stub
    		this.productBiz.addProduct();
    		//后置增强
    		log();
    		
    	}
    	private void log(){
    		System.out.println("%%%%%%%%%%%%");
    		System.out.println("操作时间"+new Date());
    		System.out.println("%%%%%%%%%%%%%");
    	}
    
    }
    
    package com.yc.biz;
    //代理类
    public class ProductBizRightProxy implements ProductBiz {
    	private ProductBiz productBiz;
    	public  ProductBizRightProxy(ProductBiz productBiz) {
    		// TODO Auto-generated constructor stub
    		this.productBiz=productBiz;
    	}
    	@Override
    	public void addProduct() {
    		//增加检查权限的功能
    		check();
    		this.productBiz.addProduct();
    	}
    	//增强的功能
    	private void check(){
    		System.out.println("==========================");
    		System.out.println("检查权限.......");
    		System.out.println("==========================");
    		
    	}
    
    }
    

    測试类改为:

    package com.yc.biz;
    
    public class Test {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    	//	ProductBiz pb=new ProductBizRightProxy(new ProductBizImpl());
    	//	pb.addProduct();
    		ProductBiz pb=new ProductBizRightProxy(new ProductBIzLogProxy(new ProductBizImpl()));
    		pb.addProduct();
    	}
    
    }
    





  • 相关阅读:
    eureka_feign学习_1
    九度 题目1183:守形数----------------我用的方法自创
    题目1179:阶乘-------------阶乘不用long long int 就不能AC
    题目1177:查找---------------字符串的函数问题
    题目1170:找最小数-------------------------------找最小值,中间值应该初始化为最大值
    题目1169:比较奇偶数个数-----------------------------这个世界不是奇数就是偶数l
    题目1075:斐波那契数列
    题目1070:今年的第几天?---------关键是闰年的判断
    题目1068:球的半径和体积----------------------------arccos(-1)要用c语言中的acos(-1)代替
    题目1067:n的阶乘--------long long int
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7284397.html
Copyright © 2011-2022 走看看