静态代理
核心思想:代理对象通过持有需要被代理类的实例,实现代理方式。
参考链接: http://www.cnblogs.com/mengdd/archive/2013/01/30/2883468.html
动态代理
a) jdk 动态代理 Proxy,
核心思想:通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,再通过invoke反射调用被代理类实例的方法,来实现代理。
缺点:被代理类必须实现一个或多个接口
参考链接:http://rejoy.iteye.com/blog/1627405
源码解析:见第四部分
cglib 动态代理
核心思想:通过生成子类字节码实现,代理类为每个委托方法都生成两个方法,以add方法为例,一个是重写的add方法,一个是CGLIB$add$0方法,该方法直接调用委托类的add方法;
底层:使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类
缺点:不能代理final修饰的类,
参考链接:http://blog.csdn.net/yakoo5/article/details/9099133/
AOP实现机制
a. 实现方式:cglib 和 jdk自带的Proxy实现
b. 策略:
1)如果是有接口声明的类进行AOP 时,spring调用的是Java.lang.reflection.Proxy 类来做处理
2)如果是没有接口声明的类时, spring通过cglib包和内部类来实现
c.配置:
<aop:aspectj-autoproxy proxy-target-class="true" />配置了这句话的话就会强制使用cglib代理。 默认就是false
JDK动态代理Demo
//业务类接口
public interface MyBusinessInterface{
public void processBusiness();
}
//业务实现类
public class MyBusinessInterfaceImpl implements MyBusinessInterface {
public void processBusiness() {
System.out.println("processing business.....");
}
}
//被代理对象调用处理程序,必须实现InvocationHandler接口
public class MyInvocationHandler implements InvocationHandler {
//所代理的真实对象
private Object target = null;
//构造器,用于传入所代理的真实对象
MyInvocationHandler(Object target){
this.target = target;
}
//需要我们实现具体业务的地方
//proxy: 所生成代理类实例
//method: 指代的是我们所要调用真实对象的某个方法的Method对象
//args: 指代的是调用真实对象某个方法时接受的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("You can do something here before process your business");
//调用目标对象的方法
Object result = method.invoke(target, args);
System.out.println("You can do something here after process your business");
//返回处理结果
return result;
}
}
//测试用例
public class Test {
public static void main(String[] args) {
//被代理真实对象
MyBusinessInterfaceImpl bpimpl = new MyBusinessInterfaceImpl();
//被代理对象调用处理程序,需传入被代理对象
MyInvocationHandler handler = new MyInvocationHandler(bpimpl);
//生成代理类实例
MyBusinessInterface bp = (MyBusinessInterface)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
//调用processBusiness
bp.processBusiness();
}
}
JDK1.8动态代理源码解析
Proxy解析
//代理类
public class Proxy implements java.io.Serializable {
private static final long serialVersionUID = -2222568056686623797L;
//代理类构造函数的参数类型
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
//代理类缓存
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
//此代理实例的调用处理程序。
protected InvocationHandler h;
private Proxy() {
}
//代理类构造函数,参数类型:constructorParams所指定
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
//获取目标代理类Class对象,需传入类加载器loader对象和被代理类实现接口数组interfaces随想
@CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)
throws IllegalArgumentException{
//拷贝接口数组
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
//校验代理类的访问问权限
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
//获取代理类Class对象
return getProxyClass0(loader, intfs);
}
//校验代理类的访问问权限,这一块比较底层,我也不明白
private static void checkProxyAccess(Class<?> caller, ClassLoader loader, Class<?>... interfaces){
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
//获取调用者类的类加载器
ClassLoader ccl = caller.getClassLoader();
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
}
//获取代理类的Clas对象
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
//如果存在给定接口的给定装入器定义的代理类存在,则只返回缓存的副本;
//否则,它将通过proxyclassfactory创建代理类
//jdk1.8后收敛到这里 生成代理类字节码过程: ProxyClassFactory中了
return proxyClassCache.get(loader, interfaces);
}
//用于带有0个实现接口的代理类的key键值
private static final Object key0 = new Object();
/*
* Key1 and Key2 are optimized for the common use of dynamic proxies
* that implement 1 or 2 interfaces.
*/
/*
* a key used for proxy class with 1 implemented interface
*/
//用于带有1个实现接口的代理类的key键值
private static final class Key1 extends WeakReference<Class<?>> {
private final int hash;
Key1(Class<?> intf) {
super(intf);
this.hash = intf.hashCode();
}
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object obj) {
Class<?> intf;
return this == obj ||
obj != null &&
obj.getClass() == Key1.class &&
(intf = get()) != null &&
intf == ((Key1) obj).get();
}
}
// //用于带有2个实现接口的代理类的key键值
private static final class Key2 exten