`

JDK动态代理小例子

 
阅读更多

1.文件列表:

业务接口:UserService

业务实现:UserServiceImpl

代理类的调用Handler实现:ProxyHandler

JUnit测试类:SpringProxyTest

2.少废话,贴代码:

package com.niewj.service;

import com.niewj.model.User;

public interface UserService {
	void add(User user);

	void delete(User user);
}
package com.niewj.service;

import com.niewj.model.User;

public class UserServiceImpl implements UserService {

	@Override
	public void add(User user) {
		System.out.println("User Saved. & ");
	}

	@Override
	public void delete(User user) {
		System.out.println("User Deleted. &");
	}
}

  

package com.niewj.service;

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

/**
 * JDK动态代理模拟
 * 
 * 1.首先明确什么是目标对象target,什么是代理对象proxy!!
 * 
 * 2.每个代理对象对象都会有一个相关的InvocationHandler对象。
 * 当代理对象生成的时候,是创建的代理对象,
 * 拿着相关的这个InvocationHandler对象,去自动调Handler类中实现的invoke方法的。
 * 下面一段话来自@javadoc@
 * <p>Each proxy instance has an associated invocation handler.
 * When a method is invoked on a proxy instance, the method
 * invocation is encoded and dispatched to the <code>invoke</code>
 * method of its invocation handler.
 * 
 * 3.还有就是我发现,我的Eclipse控制台TMD输出的顺序有误,害的老以为我人品出了什么问题,
 * 不知道控制台的信息是不是不是栈式输出的。(好绕口)
 *
 */
public class ProxyHandler implements InvocationHandler {

	// 就是要给这个目标类创建代理对象。
	private Object target;

	// 传递代理目标的实例,因为代理处理器需要。也可以用set等方法。
	public ProxyHandler(Object target) {
		this.target = target;
	}

	/*
	 * 这个方法是给代理对象调用的。 
	 * 留心的是内部的method调用的对象是目标对象,可别写错。
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object ret = null;
		// 1.调用前
		cutIntoBefore(method.getName());

		ret = method.invoke(target, args);

		// 2.调用后
		cutIntoAfter(method.getName());
		return ret;
	}

	public void cutIntoBefore(String mName) {
		System.err.println("调用____" + mName + "()____方法之前");
	}

	public void cutIntoAfter(String mName) {
		System.err.println("调用____" + mName + "()____方法完后");
	}
}

JUnit 测试类:

package com.niewj;

import java.lang.reflect.Proxy;

import org.junit.Test;

import com.niewj.model.User;
import com.niewj.service.ProxyHandler;
import com.niewj.service.UserService;
import com.niewj.service.UserServiceImpl;

public class SpringProxyTest {

	@Test
	@SuppressWarnings("rawtypes")
	public void testJDKDynamicProxy() {

		/* 1.获取UserServiceImpl对象--目标对象--也就是需要被代理的对象。 */
		UserService userService = new UserServiceImpl();
		// 获取当前类名
		Class clazz = userService.getClass();
		/*
		 * 2.获得代理对象。
		 * 每一个代理对象都有一个相关的InvocationHandler对象,通过这个handler对象的invoke来实现调用中要完成的自定义猫腻行为
		 * 。 可以使用Proxy类和自定义的调用处理逻辑来生成一个代理对象的。
		 */
		UserService userServiceProxy = (UserService) Proxy.newProxyInstance(
				clazz.getClassLoader(), clazz.getInterfaces(),
				new ProxyHandler(userService));
		userServiceProxy.add(new User("dotjar"));
		userServiceProxy.delete(new User("DDD"));
	}
}

 

3.总结:总结在代码里,look up

 

0
4
分享到:
评论
1 楼 dotjar 2013-04-18  
CGLib:
package com.niewj.service;

import java.lang.reflect.Method;

import com.niewj.model.User;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CgLibProxyImitation implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();

	/** 创建代理对象
	 * @param targetClass
	 * @return 返回代理对象
	 */
	@SuppressWarnings("rawtypes")
	public Object getProxy(Class targetClass) {
		enhancer.setSuperclass(targetClass); //设置需要创建子类的类
		enhancer.setCallback(this);
		return enhancer.create(); //通过字节码技术动态创建子类实例

	}

	public void cutIntoBefore(String mName) {
		System.err.println("调用____" + mName + "()____方法之前");
	}

	public void cutIntoAfter(String mName) {
		System.err.println("调用____" + mName + "()____方法完后");
	}

	/*  生成的代理对象调用此对象来替代原始对象
	 * 
	 * @java.lang.Object 增强对象
	 * @java.lang.reflect.Method 拦截方法
	 * @java.lang.Object[] 参数数组
	 * @net.sf.cglib.proxy.MethodProxy  用于调用父类,按需要调用多次
	 */
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		cutIntoBefore(method.getName());
		Object result = proxy.invokeSuper(obj, args);
		cutIntoAfter(method.getName());
		return result;
	}
	
	public static void main(String[] args) {
//		UserService userService = new UserServiceImpl();
		CgLibProxyImitation cglib = new CgLibProxyImitation();
		UserServiceImpl userService = (UserServiceImpl)cglib.getProxy(UserServiceImpl.class);
		userService.add(new User("dotjar"));
		userService.delete(new User("hill"));
	}
}

相关推荐

Global site tag (gtag.js) - Google Analytics