方式一:传统的代理
package cn.hc.domain;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * 代理对象创建的工厂类 * @author hc * */public class JDKProxyFactory implements InvocationHandler{ //被代理对象 private Object target; public JDKProxyFactory(Object target){ this.target=target; } //创建代理 public Object createProxy(){ //三个参数:类加载器 实现接口 invocationHandler return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { // TODO Auto-generated method stub //调用目标真是的方法 System.out.println("日志已经被记录"); return arg1.invoke(target, arg2); }}
此种方法的缺陷在于:被代理的类必须实现接口
package cn.hc.domain;//代理对象的接口public interface UserDao { public void save(); public void update();}package cn.hc.domain;/** * 被代理的目标对象 * @author hc * */public class UserDaoImpl implements UserDao { public void save() { // TODO Auto-generated method stub System.out.println("添加用户"); } public void update() { // TODO Auto-generated method stub System.out.println("更新用户"); }}//测试类package cn.hc.domain;import org.junit.Test;public class TestProxy { @Test public void testJdkProxy(){ //测试jdk动态代理 //1真实目标对象 UserDao userDao=new UserDaoImpl(); //System.out.println(userDao); UserDao proxy=(UserDao) new JDKProxyFactory(userDao).createProxy(); proxy.save(); proxy.update(); }}
测试结果:
日志已经被记录
添加用户
日志已经被记录
更新用户
方式2:cglib动态代理
package cn.hc.cglibProxy;import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;public class CGlibProxyFactory implements MethodInterceptor{ private Object target; public CGlibProxyFactory(Object target){ this.target=target; } //创建代理对象的方法 public Object createProxy() { //创建Enhance对象 Enhancer enhancer=new Enhancer(); //cglib创建代理,对目标对象创建子类对象 enhancer.setSuperclass(target.getClass()); //传入callback对象,对目标增强 enhancer.setCallback(this); return enhancer.create(); } //arg3 用于执行父类的方法 public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { // TODO Auto-generated method stub System.out.println("开始记录日志"); return arg1.invoke(target,arg2); }}
package cn.hc.cglibProxy;public class ProductDao { public void add(){ System.out.println("添加"); } public void delete(){ System.out.println("删除"); }}//测试方法package cn.hc.cglibProxy;import org.junit.Test;public class CGlibTest { @Test public void test1(){ //创建目标对象 ProductDao dao=new ProductDao(); ProductDao proxy=(ProductDao) new CGlibProxyFactory(dao).createProxy(); proxy.add(); proxy.delete(); }}