jdk动态代理和cglib动态代理都是增强被代理对象的手段之一,jdk动态代理顾名思义是由java官方提供的一种,而cglib是第三方的开源项目
有些书籍中的提到的是委托方和被委托方,二者的对应关系正好相反,即委托方=被代理对象,被委托方=代理对象
二者的区别:
- cglib实现原理是通过集成被代理类来实现动态代理的,因而类的修饰符不能含有final修饰符,并且方法同样不能使用static和final等修饰符,若含有就不能实现增强方法
- jdk实现原理:代理对象和被代理对象必须同时实现同一接口(即含有同一套规范).
cglib代理:
cglib被代理对象:
cglib测试方法:
cglib输出结果:
"D:\Program Files\Java\jdk1.8.0_151\bin\java" "-javaagent:D:\Program
开启事务
目标对象方法
关闭事务
Process finished with exit code 0
JDK代理实现:首先来看一下实现大概结构图
接口实现方法
public interface accountService {
void say();
}
被代理对象:
public class accountServiceImpl implements accountService {
@Override
public void say() {
System.out.println("我是被代理对象方法");
}
}
代理工厂方法:
package jdkProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* @author iCopper
* @ 2018/8/18 --8:47
*/
public class jdkFactory implements InvocationHandler {
//目标对象
private Object target;
//constructor
public jdkFactory(Object target) {
this.target = target;
}
//对外提供实例化代理对象方法
//方法一
/*
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("增强前方法");
Object resultMethod = method.invoke(target, args);
System.out.println("增强后方法");
return resultMethod;
}
});
}
*/
//对外提供实例化代理对象方法
//方法二
/*
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new myInhandlervacation());
}
private class myInhandlervacation implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("增强前方法");
Object resultMethod = method.invoke(target, args);
System.out.println("增强后方法");
return resultMethod;
}
}
*/
//对外提供实例化代理对象方法
//方法三
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
this); //这里的this指代的是InvacationHandler()
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("增强前方法");
Object resultMethod = method.invoke(target, args);
System.out.println("增强后方法");
return resultMethod;
}
}
测试方法;
package jdkProxy;
import com.itClass.Spring.DynProxyJDK.JdkProxyFactory;
import jdkProxy.Impl.jdkProxyImpl;
/*
* @author iCopper
* @ 2018/8/18 --9:15
*/
public class Demo {
// public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
// Class clazz = Class.forName("jdkProxy.Impl.jdkProxyImpl");
// Method[] methods = clazz.getDeclaredMethods();
// for (Method method : methods) {
// System.out.println(method.getName());
// }
// Field[] fields = clazz.getDeclaredFields();
// for (Field field : fields) {
// System.out.println(field.getName());
// }
// System.out.println(clazz.getDeclaredField("field01"));
// }
public static void main(String[] args) {
jdkProxyImpl target = new jdkProxyImpl(); //创建被代理对象
jdkFactory jdkFactory = new jdkFactory(target);
jdkProxy proxyInstance = (jdkProxy) jdkFactory.getProxyInstance();
proxyInstance.say();
}
}
代理工厂的三种实现形式中,前两种是不需要实现InvocationHandler接口,第三种是需要实现该接口,第一种是匿名内部类,第二中是内部类