1. 基于JDK动态代理,只能基于接口的,其中2个重要的类或者接口,Proxy和InvocationHandler。
调用Proxy类中的newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)方法可以创建一个动态代理对象,但是这个方法需要3个参数,前两个参数是固定的,但第三个参数比较麻烦,需要我们创建一个类MyInvocationHandler来实现InvocationHandler接口,这个类里面要重写invoke()方法。
// MyInvocationHandler
package com.abai.test2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target = null;
public MyInvocationHandler(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("--------log begin--------");
method.invoke(target, args);
System.out.println("--------log end----------");
return null;
}
}
// test 入口
package com.abai.test2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/*
* 动态代理的第一种实现方式,基于jdk的动态代理
* 只能对继承接口的类实现动态代理
* 为该UserDao添加日志功能
*
*/
public class Test {
public static void main(String[] args){
UserDaoImp udi = new UserDaoImp();
udi.add();
udi.delete();
udi.query();
udi.update();
System.out.println("===================================");
// 代理开始
// 代理对象处理器
InvocationHandler myInvocationHandler = new MyInvocationHandler(udi);
UserDao proxy = (UserDao) Proxy.newProxyInstance(udi.getClass().getClassLoader(), udi.getClass().getInterfaces(), myInvocationHandler);
proxy.add();
proxy.delete();
proxy.query();
proxy.update();
}
}
2.基于cglib的动态代理。
cglib可以对任意类生成代理对象,它的原理是对目标对象进行继承代理,如果目标对象被final修饰,那么该类无法被cglib代理。