JDK动态代理

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

 

你可能感兴趣的:(JDK动态代理)