核心思想:代理对象通过持有需要被代理类的实例,实现代理方式。
参考链接: http://www.cnblogs.com/mengdd/archive/2013/01/30/2883468.html
a) jdk 动态代理 Proxy,
核心思想:通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,再通过invoke反射调用被代理类实例的方法,来实现代理。
缺点:被代理类必须实现一个或多个接口
参考链接:http://rejoy.iteye.com/blog/1627405
源码解析:见第四部分
核心思想:通过生成子类字节码实现,代理类为每个委托方法都生成两个方法,以add方法为例,一个是重写的add方法,一个是CGLIB$add$0方法,该方法直接调用委托类的add方法;
底层:使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类
缺点:不能代理final修饰的类,
参考链接:http://blog.csdn.net/yakoo5/article/details/9099133/
a. 实现方式:cglib 和 jdk自带的Proxy实现
b. 策略:
1)如果是有接口声明的类进行AOP 时,spring调用的是Java.lang.reflection.Proxy 类来做处理
2)如果是没有接口声明的类时, spring通过cglib包和内部类来实现
c.配置:
配置了这句话的话就会强制使用cglib代理。 默认就是false
//业务类接口
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();
}
}
//代理类
public class Proxy implements java.io.Serializable {
private static final long serialVersionUID = -2222568056686623797L;
//代理类构造函数的参数类型
private static final Class[] constructorParams =
{ InvocationHandler.class };
//代理类缓存
private static final WeakCache[], 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 extends WeakReference<Class> {
private final int hash;
//弱引用对象:存放第二个接口类对象
private final WeakReference> ref2;
Key2(Class intf1, Class intf2) {
super(intf1);
hash = 31 * intf1.hashCode() + intf2.hashCode();
ref2 = new WeakReference>(intf2);
}
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object obj) {
Class intf1, intf2;
return this == obj ||
obj != null &&
obj.getClass() == Key2.class &&
(intf1 = get()) != null &&
intf1 == ((Key2) obj).get() &&
(intf2 = ref2.get()) != null &&
intf2 == ((Key2) obj).ref2.get();
}
}
// 这里用于带有>=3个实现接口的代理类的key键值(可以当实现任意数目接口的代理的key)
private static final class KeyX {
//接口数组对象的hash值
private final int hash;
//弱引用对象数组:存放表示接口的类对象数组
private final WeakReference>[] refs;
@SuppressWarnings("unchecked")
KeyX(Class[] interfaces) {
hash = Arrays.hashCode(interfaces);
//构造一个弱引用对象数组
refs = (WeakReference>[])new WeakReference[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
refs[i] = new WeakReference<>(interfaces[i]);
}
}
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object obj) {
return this == obj ||
obj != null &&
obj.getClass() == KeyX.class &&
equals(refs, ((KeyX) obj).refs);
}
private static boolean equals(WeakReference>[] refs1,
WeakReference>[] refs2) {
//长度是否相等
if (refs1.length != refs2.length) {
return false;
}
//弱引用对象数组内接口类是否相同
for (int i = 0; i < refs1.length; i++) {
Class intf = refs1[i].get();
if (intf == null || intf != refs2[i].get()) {
return false;
}
}
return true;
}
}
//将接口数组映射到一个最佳键的函数,其中表示接口的类对象为弱引用。
private static final class KeyFactory
implements BiFunction<ClassLoader, Class[], Object>
{
@Override
public Object apply(ClassLoader classLoader, Class[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // the most frequent
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
}
//一个工厂函数生成‘给定类装载器和接口数组的代理类’。
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class[], Class>
{
//所有代理类名称的前缀
private static final String proxyClassNamePrefix = "$Proxy";
//用于生成唯一代理类名称的下一个数字
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class apply(ClassLoader loader, Class[] interfaces) {
Map, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class intf : interfaces) {
//验证intf接口类Class对象是否为给定的classloder解析的
Class interfaceClass = null;
try {
//指定类加载器获取接口类class对象,
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
//验证是否为同一个接口类对象,
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
//验证类对象是否为接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
* 验证此接口不是副本。
*/
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
//定义代理类的包
String proxyPkg = null;
//定义代理类的修饰符:public和final类型
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
* 记录一个非公共代理接口的包,以便在同一个包中定义代理类。验证所有非公共代理接口都在同一个包中。
*/
for (Class intf : interfaces) {
//获取修饰符
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) { //不是public修饰符
//则定义代理类的修饰符符:final
accessFlags = Modifier.FINAL;
//获取接口类名称,如:com.text.MyInterface
String name = intf.getName();
int n = name.lastIndexOf('.');
//获取包名,如:com.text
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
//获取包名称
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) { //interfaces含有来自不同包的非公共接口,抛错
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
//如果没有非公开的代理接口,使用com.sun.proxy作为包名称
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
//选择要生成的代理类的名称。
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
//真正生成指定的代理类字节码的地方
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//生成Calss对象
return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}
}
}
//生成代理类对象
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
throws IllegalArgumentException {
//调用处理程序不能为空
Objects.requireNonNull(h);
//拷贝接口数组对象
final Class[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
//查找或生成指定的代理类。
Class cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
* 调用指定的调用处理程序的构造函数
*/
try {
if (sm != null) {
//校验新代理类的权限
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//获取代理类构造函数,参数类型必须为InvocationHandler
final Constructor cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//构造函数不是public,则设置当前构造函数为访问权限
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//调用构造函数构造代理类实例,入参数为‘调用处理程序’的实例,看到这里应该就明白jdk怎么实现动态代理的吧!
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
private static void checkNewProxyPermission(Class caller, Class proxyClass) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
//调用者类加载器
ClassLoader ccl = caller.getClassLoader();
//代理类的类加载器
ClassLoader pcl = proxyClass.getClassLoader();
// do permission check if the caller is in a different runtime package
// of the proxy class
//获取代理类的包名
int n = proxyClass.getName().lastIndexOf('.');
String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
//获取调用者包名
n = caller.getName().lastIndexOf('.');
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
//类加载不相同或包名不相同,校验权限
if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
}
}
}
}
public static boolean isProxyClass(Class cl) {
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
{
//验证该对象实际上是否为上一个代理实例。
if (!isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("not a proxy instance");
}
final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class ihClass = ih.getClass();
Class caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
}
return ih;
}
private static native Class defineClass0(ClassLoader loader, String name,
byte[] b, int off, int len);
}
//用处存放
final class WeakCache<K, P, V> {
private final ReferenceQueue refQueue = new ReferenceQueue<>();
// the key type is Object for supporting null key
//Map<类加载器,Map<接口数组对象key,代理类工厂Factory或代理类包装对象LookupValue>
private final ConcurrentMap
import dynamic.proxy.UserService;
import java.lang.reflect.*;
public final class $Proxy11 extends Proxy
implements UserService
{
// 构造方法,参数就是刚才传过来的MyInvocationHandler类的实例
public $Proxy11(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
public final boolean equals(Object obj)
{
try
{
return ((Boolean)super.h.invoke(this, m1, new Object[] {
obj
})).booleanValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
/**
* 这个方法是关键部分
*/
public final void add()
{
try
{
// 实际上就是调用MyInvocationHandler的public Object invoke(Object proxy, Method method, Object[] args)方法,第二个问题就解决了
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final int hashCode()
{
try
{
return ((Integer)super.h.invoke(this, m0, null)).intValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final String toString()
{
try
{
return (String)super.h.invoke(this, m2, null);
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
private static Method m1;
private static Method m3;
private static Method m0;
private static Method m2;
// 在静态代码块中获取了4个方法:Object中的equals方法、UserService中的add方法、Object中的hashCode方法、Object中toString方法
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
Class.forName("java.lang.Object")
});
m3 = Class.forName("dynamic.proxy.UserService").getMethod("add", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
}
catch(NoSuchMethodException nosuchmethodexception)
{
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
}