注意在使用JDK提供的动态代理要求我们的目标对象必须实现接口。我们可以通过调用java.lang.reflect.Proxy的静态方法
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
loader是类装载器
interfaces是目标对象实现的一系列接口
h是一个实现 InvocationHandler 接口的类 , 我们对代理对象的所有操作都经过它处理
1、接口:
package proxy.myproxy.dynamicProxy; public interface UserDao { void save(); }
2、实现类:
package proxy.myproxy.dynamicProxy; public class UserDaoImpl implements UserDao { public void save() { System.out.println("UserDao save()"); } }
3、动态代理
package proxy.myproxy.dynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class InvocationHandlerImpl implements InvocationHandler { private Object target; public InvocationHandlerImpl(Object target){ this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开始记录日志"); Object obj = method.invoke(target, args); System.out.println("结束记录日志"); return obj; } }
4、测试类
package proxy.myproxy.dynamicProxy; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { UserDao userDao = new UserDaoImpl(); UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandlerImpl(userDao)); userDaoProxy.save(); } }
-----------------------------------------------------------------------------------------------------------------------------------------
JDK动态代理
public class JDKProxy implements InvocationHandler { private Object targetObject;//代理的目标对象 public Object createProxyInstance(Object targetObject){ this.targetObject = targetObject; /* * 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器 * 第二个参数设置代理类实现的接口 * 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法 */ return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(this.targetObject, args);//把方法调用委派给目标对象 } } 当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。
--------------------------------------------------------------------------------------------------------------------------------------------
使用CGLIB生成代理
public class CGLIBProxy implements MethodInterceptor { private Object targetObject;//代理的目标对象 public Object createProxyInstance(Object targetObject){ this.targetObject = targetObject; Enhancer enhancer = new Enhancer();//该类用于生成代理对象 enhancer.setSuperclass(this.targetObject.getClass());//设置父类 enhancer.setCallback(this);//设置回调用对象为本身 return enhancer.create(); } public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { return methodProxy.invoke(this.targetObject, args); } } CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。