Java动态代理实现接口方法

最近正在看Mybatis源码,重点研究了自定义Mapper接口里方法实现如何与xml配置文件进行绑定,最后了解到是通过java动态代理实现了接口方法。

主要使用了Proxy.newProxyInstance(loader, interfaces, invocationHandler方法来实现实例化,第一个参数为classLoader,第二个参数为要实例化的接口,第三个是InvocationHanler接口,需要实现此接口来实现方法的具体操作。例:

public void proxyTest() throws ClassNotFoundException,
			InstantiationException, IllegalAccessException {
		MethodProxy invocationHandler = new MethodProxy();
		Object newProxyInstance = Proxy.newProxyInstance(
				IUserService.class.getClassLoader(),
				new Class[] { IUserService.class }, invocationHandler);
		IUserService userService = (IUserService) newProxyInstance;
		User query = userService.query();
		System.out.println("query result->" + query.toString());
	}
执行结果:



具体代码实现如下(仅为了说明实现方式,请忽略结构层次和命名规范):

public class MethodProxy implements InvocationHandler {

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("执行前");
		if (Object.class.equals(method.getDeclaringClass())) {
			try {
				return method.invoke(this, args);
			} catch (Throwable t) {
				t.printStackTrace();
			}
		} else {
//			System.out.println("调用方法名:"+method.getName());
			return run(method, args);
		}
		System.out.println("执行后");
		return null;
	}
	
	UserDao dao = null;
	//具体实现通过方法名绑定。
	public Object run(Method method,Object[] args){
		if(dao == null){
			dao = new UserDao();
		}
		Object ret = null;
		String name = method.getName();
		if(name.equals("add")){
			dao.add(args);
		}else if(name.equals("delete")){
			dao.delete();
		}else if(name.equals("query")){
			ret = dao.query();
		}
		return ret;
	}
	
	class UserDao {
		public void add(Object[] args){
			System.out.println("dao add");
			for (Object object : args) {
				System.out.print(object+",");
			}
		}
		public void delete(){
			System.out.println("dao delete");
		}
		public User query(){
			return new User("123", "济南", 22, "备注");
		}
	}
}

public interface IUserService {

	public void add(User user);
	
	public User query();
	
	public void delete(int id);

}

public class User {
	private String id;
	private String username;
	private int age;
	private String remarks;

	public User(String id, String username, int age, String remarks) {
		super();
		this.id = id;
		this.username = username;
		this.age = age;
		this.remarks = remarks;
	}
 ……
       @Override
       public String toString() {
           return "User [id=" + id + ", username=" + username + ", age=" + age
                + ", remarks=" + remarks + "]";
    }
}
本demo所展示的是具体接口的实现方法,为保证通用性,则可通过泛型实现接口实例化的通用方法。  (参考mybatis-src)

例地:

你可能感兴趣的:(Java)