java 动态代理

此模式一般用在不修改源代码的情况下对类进行增强。

一、proxy类使用

以下给出简单的使用方法详见代码:

 

  • 接口与实现类
package test;
/**
 * person接口
 * @author Administrator
 *
 */
public interface Person {
	
	public void say();
	
	
}


package test;

/**
 * person实现类
 * @author Administrator
 *
 */
public class Student implements Person{

	@Override
	public void say() {
		System.out.println("我是学生!");
	}

}

获得代理的工具类

package test;

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


/**
 * #演示代理的工具类
 * @author Administrator
 *
 */
public class ProxyUtils2 {
	
	/**
	 * #获取类代理对象的工具
	 * @return
	 */
	public static Object getProxy(final Object o) {
		/*
		 * #使用java.lang.reflect.Proxy获得代理
		 * #参数1:代理接口的classloader
		 * #参数2:代理接口的interface
		 * #参数3:InvocationHandler的实现类或内部类,本例使用内部类实现。
		 */
		Object proxy =  (Person) Proxy.newProxyInstance(o.getClass().getClassLoader(),
				o.getClass().getInterfaces(), new InvocationHandler() {
					
					/*
					 * #参数1不要使用
					 * #参数2是proxy调用的实现类的方法
					 * #参数3是方法的参数
					 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
					 */
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						//在invoke前执行的方法,可以使记录日志开启事务等。。。
						System.out.println("执行" + method.getName() + "前。");
						//执行proxy调用的实现类的方法
						method.invoke(o, args);
						//在invoke后执行的方法,可以使记录日志提交回滚事务等。。。
						System.out.println("执行" + method.getName() + "后。");
						
						return null;
					}
				});
		//返回该代理
		return proxy;
		
	} 
}

测试类

package test;

import org.junit.Test;

/**
 * #代理模式的测试类
 * @author Administrator
 *
 */
public class DemoProxy {
	
	@Test
	public void run1() {
		//通过proxyUtils获得需代理的类
		Person proxy = (Person) ProxyUtils2.getProxy(new Student());
		//执行该类的方法
		proxy.say();
	}
}

执行结果:

 

二、使用CGLIB

 * CGLIB特点是代理没有借口的类,通过继承的方法来增强方法
 * 在Spring框架核心包中已经引入了CGLIB的开发包了。所以直接引入Spring核心开发包即可

需要注意的是用cblib代理没有借口的类

详见代码:

 

  • 需要代理的类
package test;

public class Teacher {
	
	public void say() {
		System.out.println("我是老师");
	}
}

 

  • 代理工具类
package test;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/**
 * #演示使用cblib代理的工具类(无接口)
 * cblib特点是代理没有借口的类,通过继承的方法来增强方法
 * 在Spring框架核心包中已经引入了CGLIB的开发包了。所以直接引入Spring核心开发包即可
 * @author Administrator
 *
 */
public class ProxyUtils {
	

	public static Object getProxy(final Object obj) {
		// 实例化cglib的核心类enhancer
		Enhancer enhancer = new Enhancer();
		//设置enhancer的父类
		enhancer.setSuperclass(obj.getClass());
		//设置enhancer的回调函数,使用callback的实现接口MethodInterceptor
		enhancer.setCallback(new MethodInterceptor() {

			@Override
			public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//				System.out.println("method: " + method.getName());
				System.out.println("代理前执行操作");
				
				methodProxy.invoke(obj, args);
				
				System.out.println("代理后执行操作");
				return null;
			}
		});
		return enhancer.create();
			
	}
}
  • 测试类
package test;

import org.junit.Test;

/**
 * #代理模式的测试类
 * @author Administrator
 *
 */
public class DemoProxy {
	
	@Test
	public void run() {
		//通过proxyUtils获得需代理的类
		Teacher proxy =  (Teacher) ProxyUtils.getProxy(new Teacher());
		//执行该类的方法
		proxy.say();
	}
	
}
  • 测试结果输出

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值