• Java动态代理的两种实现方式:


    方式一:传统的代理

    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();
      }
    }
    
  • 相关阅读:
    未将对象引用设置到对象的实例--可能出现的问题总结
    Unity3d物体模型(实现旋转缩放平移自动旋转)
    Java实现斐波那契数列的多种方法
    Java实现斐波那契数列的多种方法
    Java实现斐波那契数列的多种方法
    Java实现斐波那契数列的多种方法
    Java实现斐波那契数列的多种方法
    Java中环境变量PATH与CLASSPATH的区别
    Java中环境变量PATH与CLASSPATH的区别
    Java中环境变量PATH与CLASSPATH的区别
  • 原文地址:https://www.cnblogs.com/woolhc/p/4926329.html
Copyright © 2020-2023  润新知