java原生动态代理实现demo

本文通过具体实例详细介绍了Java动态代理的实现过程,包括创建数据Bean、服务层接口及其实现类,以及如何利用Proxy和InvocationHandler实现方法拦截。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这只是一个demo试验,理论性的只是较少;

1,建立数据bean:User.java

/**
 * User.java
 * Created at 2014年8月27日
 * Created by mengfanyuan 
 * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
 */
package com.mfy.test.proxy.bean;

/**
 * <p>
 * ClassName: User
 *</p>
 * <p>
 * Description: TODO
 * </p>
 * <p>
 * Author: mengfanyuan
 * Email:kalvenmeng@163.com
 * </p>
 * <p>
 * Date: 2014年8月27日
 * </p>
 */
public class User {
	private Integer id; // 用户Id
	private String userName; //用户名
	private String passWord; //密码
	
	public User() {
		super();
	}

	public User(Integer id, String userName, String passWord) {
		super();
		this.id = id;
		this.userName = userName;
		this.passWord = passWord;
	}
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassWord() {
		return passWord;
	}
	public void setPassWord(String passWord) {
		this.passWord = passWord;
	}
}

2,建服务层接口(目标类必须实现接口):IPersonService.java

/**
 * IPersonService.java
 * Created at 2014年8月27日
 * Created by mengfanyuan 
 * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
 */
package com.mfy.test.proxy.service;

import com.mfy.test.proxy.bean.User;

/**
 * <p>
 * ClassName: IPersonService
 *</p>
 * <p>
 * Description: TODO
 * </p>
 * <p>
 * Author: mengfanyuan
 * Email:kalvenmeng@163.com
 * </p>
 * <p>
 * Date: 2014年8月27日
 * </p>
 */
public interface IUserService {
	void save(User user);
	void update(User user);
	void delete(Integer id);
}<strong>
</strong>
3,服务层实现类:UserServiceImp.java
/**
 * UserServiceImp.java
 * Created at 2014年8月27日
 * Created by mengfanyuan 
 * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
 */
package com.mfy.test.proxy.service.imp;

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.service.IUserService;

/**
 * <p>
 * ClassName: UserServiceImp
 *</p>
 * <p>
 * Description: TODO
 * </p>
 * <p>
 * Author: mengfanyuan
 * Email:kalvenmeng@163.com
 * </p>
 * <p>
 * Date: 2014年8月27日
 * </p>
 */
public class UserServiceImp implements IUserService {

	@Override
	public void save(User user) {
		// TODO Auto-generated method stub
		System.out.println("新增用户:" + user.getUserName());
	}

	@Override
	public void update(User user) {
		// TODO Auto-generated method stub
		System.out.println("更新用户:" + user.getUserName());
	}

	@Override
	public void delete(Integer id) {
		// TODO Auto-generated method stub
		System.out.println("删除用户Id:" + id);
	}

}
4,目标方法拦截处理实现类:ProxyHandle.java

/**
 * ProxyHandle.java
 * Created at 2014年8月27日
 * Created by mengfanyuan 
 * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
 */
package com.mfy.test.proxy.handle;

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

/**
 * <p>
 * ClassName: ProxyHandle
 *</p>
 * <p>
 * Description: 代理拦截处理类
 * </p>
 * <p>
 * Author: mengfanyuan
 * Email:kalvenmeng@163.com
 * </p>
 * <p>
 * Date: 2014年8月27日
 * </p>
 */
public class ProxyHandle implements InvocationHandler {
	private Object target;
	
	
	public ProxyHandle(Object target) {
		this.target = target;
	}
	
	/* (non-Javadoc)
	 * <p>Title: invoke</p>
	 * <p>Description: 在该方法中对目标类方法调用的处理 </p>
	 * @param proxy
	 * @param method
	 * @param args
	 * @return
	 * @throws Throwable
	 * @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 {
		// TODO Auto-generated method stub
		System.out.println(method.getName() + "方法执行前..");
		Object result = method.invoke(target, args);
		System.out.println(method.getName() + "方法执行后...");
		return result;
	}

}
5:,动态代理类生产器:ProxyFactory.java

/**
 * ProxyFactory.java
 * Created at 2014年8月27日
 * Created by mengfanyuan 
 * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
 */
package com.mfy.test.proxy.handle;

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

/**
 * <p>
 * ClassName: ProxyFactory
 *</p>
 * <p>
 * Description: TODO
 * </p>
 * <p>
 * Author: mengfanyuan
 * Email:kalvenmeng@163.com
 * </p>
 * <p>
 * Date: 2014年8月27日
 * </p>
 */
public class ProxyFactory {
	
	public static Object createProxyObj (Class targetInterface,InvocationHandler h) throws Exception {
		
		return  Proxy.newProxyInstance(targetInterface.getClassLoader(), 
				new Class[]{targetInterface}, h);
	}
}
6,测试类:TestMain.java

/**
 * TestMain.java
 * Created at 2014年8月27日
 * Created by mengfanyuan 
 * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
 */
package com.mfy.test.proxy.main;

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.handle.ProxyFactory;
import com.mfy.test.proxy.handle.ProxyHandle;
import com.mfy.test.proxy.service.IUserService;
import com.mfy.test.proxy.service.imp.UserServiceImp;

/**
 * <p>
 * ClassName: TestMain
 *</p>
 * <p>
 * Description: TODO
 * </p>
 * <p>
 * Author: mengfanyuan
 * Email:kalvenmeng@163.com
 * </p>
 * <p>
 * Date: 2014年8月27日
 * </p>
 */
public class TestMain {
	
	public static void main(String[] args) throws Exception {
		User user = new User(1,"kalven","11111111");
		IUserService serviceProxy = (IUserService)ProxyFactory.createProxyObj(IUserService.class, new ProxyHandle(new UserServiceImp()));
		serviceProxy.save(user);
		System.out.println();
		serviceProxy.update(user);
		System.out.println();
		serviceProxy.delete(user.getId());
	}
	
}
7,输出结果:

save方法执行前..
新增用户:kalven
save方法执行后...


update方法执行前..
更新用户:kalven
update方法执行后...


delete方法执行前..
删除用户Id:1
delete方法执行后...


8,结果分析总结:

    从输出结果可以看到对目标类中的方法的调用都被拦截到ProxyHandle.java类中的方法invoke中去了;实现动态代理的关键类是Proxy和接口InvocationHandler;

9,对生成的动态代理类分析:

 将第六步的测试类修改一下:

/**
 * TestMain.java
 * Created at 2014年8月27日
 * Created by mengfanyuan 
 * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
 */
package com.mfy.test.proxy.main;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import sun.misc.ProxyGenerator;

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.handle.ProxyFactory;
import com.mfy.test.proxy.handle.ProxyHandle;
import com.mfy.test.proxy.service.IUserService;
import com.mfy.test.proxy.service.imp.UserServiceImp;

/**
 * <p>
 * ClassName: TestMain
 *</p>
 * <p>
 * Description: TODO
 * </p>
 * <p>
 * Author: mengfanyuan
 * Email:kalvenmeng@163.com
 * </p>
 * <p>
 * Date: 2014年8月27日
 * </p>
 */
public class TestMain {
	
	public static void main(String[] args) throws Exception {
		User user = new User(1,"kalven","11111111");
		IUserService serviceProxy = (IUserService)ProxyFactory.createProxyObj(IUserService.class, new ProxyHandle(new UserServiceImp()));
		serviceProxy.save(user);
		System.out.println();
		serviceProxy.update(user);
		System.out.println();
		serviceProxy.delete(user.getId());
		
		createProxyClassFile();
	}
	
	
	
	public static void createProxyClassFile() throws Exception{
		String fileName = "UserServiceProxy";
		byte[] date = ProxyGenerator.generateProxyClass(fileName, new Class[]{IUserService.class});
		FileOutputStream out = new FileOutputStream(fileName + ".class");
		out.write(date);
		out.close();
	}
	
}
执行完毕后可以在工程根路径下找到文件:UserServiceProxy.class

可以对该文件进行反编译查看生成的代理类的内容:

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.service.IUserService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class UserServiceProxy
  extends Proxy
  implements IUserService
{
  private static Method m1;
  private static Method m5;
  private static Method m4;
  private static Method m0;
  private static Method m3;
  private static Method m2;
  
  public UserServiceProxy(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }
  
  public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final void update(User paramUser)
    throws 
  {
    try
    {
      this.h.invoke(this, m5, new Object[] { paramUser });
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final void delete(Integer paramInteger)
    throws 
  {
    try
    {
      this.h.invoke(this, m4, new Object[] { paramInteger });
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final void save(User paramUser)
    throws 
  {
    try
    {
      this.h.invoke(this, m3, new Object[] { paramUser });
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final String toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m5 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("update", new Class[] { Class.forName("com.mfy.test.proxy.bean.User") });
      m4 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("delete", new Class[] { Class.forName("java.lang.Integer") });
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m3 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("save", new Class[] { Class.forName("com.mfy.test.proxy.bean.User") });
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}


10,总结:

诚然,Proxy已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫Proxy。Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。有很多条理由,人们可以否定对 class代理的必要性,但是同样有一些理由,相信支持class动态代理会更美好。接口和类的划分,本就不是很明显,只是到了Java中才变得如此的细化。如果只从方法的声明及是否被定义来考量,有一种两者的混合体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内在的价值。此外,还有一些历史遗留的类,它们将因为没有实现任何接口而从此与动态代理永世无缘。如此种种,不得不说是一个小小的遗憾。但是,不完美并不等于不伟大,伟大是一种本质,Java动态代理就是佐例。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值