此模式一般用在不修改源代码的情况下对类进行增强。
一、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();
}
}
- 测试结果输出