注意在使用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修饰符的方法。