码迷,mamicode.com
首页 > 其他好文 > 详细

动态代理

时间:2015-08-07 16:17:03      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:

  面向接口的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);
		//在客户端我们调用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);
		//在客户端我们调用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();
	}

}





版权声明:本文为博主原创文章,未经博主允许不得转载。

动态代理

标签:

原文地址:http://blog.csdn.net/ac_great/article/details/47339625

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!