由java的代理技术展开

代理模式

开闭原则 通过访问代理对象间接的访问到目标对象,期间可以无侵入的对目标对象的功能增强。即在对既有代码不改动的情况下进行功能的扩展
JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础

代理模式

静态代理

静态代理中代理类在编译期就已经确定,而动态代理则是JVM运行时动态生成,静态代理的效率相对动态代理来说相对高一些,但是静态代理代码冗余大,一单需要修改接口,代理类和委托类都需要修改。

//接口Subject
interface HelloService {
    void sayHello();
}

//委托类 目标类 RealSubject
class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("Hello World!");
    }
}
//代理类
class HelloServiceProxy implements HelloService {
	//编译期已经指定改代理类的代理接口- //代理类持有目标类的引用
    private HelloService helloService;
    
    //初始化目标类
    public HelloServiceProxy(HelloService helloService) {
        this.helloService = helloService;
    }
    
    @Override
    public void sayHello() {
        System.out.println("Before say hello...");
        helloService.sayHello();
        System.out.println("After say hello...");
    }
}
//测试类
public class HelloServiceProxyTest {
    
    public static void main(String[] args) {
        HelloService helloService = new HelloServiceImpl();
        HelloServiceProxy proxy = new HelloServiceProxy(helloService);
        proxy.sayHello();
    }
}

动态代理

jdk动态代理

是靠反射来对该委托类增强
代理类和委托类都要实现同一个接口。

jdk动态代理代码demo

public interface HelloService {
    public String sayHello(String name);
}
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name){
        System.out.println("你好啊:"+name);
        return "ok";
    }
}
//执行目标方法和增强
public class MyInvocationHandler implements InvocationHandler {
//代理类持有目标类的引用
    private Object target;

	//注入被代理类
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before say hello...");
        Object ret = method.invoke(target, args);
        System.out.println("After say hello...");
        return ret;
    }
}

public class Test {

    public static void main(String[] args) {
        //j具体实现类
        HelloService helloService = new HelloServiceImpl();

        //代理类
        InvocationHandler invocationHandler =   new MyInvocationHandler(helloService);

        //产生代理对象 com.xx.chao.HelloServiceImpl@71e7a66b
        Object o = Proxy.newProxyInstance(helloService.getClass().getClassLoader(), helloService.getClass().getInterfaces(), invocationHandler);
        HelloService helloServiceProxy=(HelloService) o;
        String result = helloServiceProxy.sayHello("张天闻");
        //System.out.println(o);//chao.HelloServiceImpl@71e7a66b 调用的是HelloServiceImpl.toString()方法也会被代理。
        System.out.println(o.getClass().getName());//com.sun.proxy.$Proxy0
        System.out.println(o.getClass().getSimpleName());//$Proxy0
        System.out.println(o.getClass().getCanonicalName());//com.sun.proxy.$Proxy0
        System.out.println(result);//ok

        //ProxyUtil.generateClassFile(o.getClass(),o.getClass().getSimpleName());
    }
}

产生的代理类
上图是产生的HelloServiceImpl的代理类。

源码解析

  1. 源码分析

Proxy类的newProxyInstance方法

public class Proxy implements java.io.Serializable {

	.....
	 final Class<?>[] intfs = interfaces.clone();
	 final SecurityManager sm = System.getSecurityManager();
	 if (sm != null) {
	 	// 检查权限 1 暂且不表
	     checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
	 }
	/*
	 * Look up or generate the designated proxy class.
	 */
	Class<?> cl = getProxyClass0(loader, intfs);
	
	/*
	 * Invoke its constructor with the designated invocation handler.
	 */
	try {
	    if (sm != null) {
	    	//检查权限 2 暂且不表
	        checkNewProxyPermission(Reflection.getCallerClass(), cl);
	    }
	}catch()
	....
    private static Class<?> getProxyClass0(ClassLoader loader,  Class<?>... interfaces) {
    
     // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
	//ProxyClassFactory 是其内部的一个静态类
        return proxyClassCache.get(loader, interfaces);
	}

private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>>{
        // prefix for all proxy class names
        private static final String proxyClassNamePrefix = "$Proxy";

        // next number to use for generation of unique proxy class names
        private static final AtomicLong nextUniqueNumber = new AtomicLong();

        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
            }

            String proxyPkg = null;     // package to define proxy class in
            if (proxyPkg == null) {
                // if no non-public proxy interfaces, use com.sun.proxy package
    			//com.sun.proxy
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }

            /*
             * Choose a name for the proxy class to generate.
             */
            long num = nextUniqueNumber.getAndIncrement();
            //com.sun.proxy.$Proxy0
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * Generate the specified proxy class. ProxyGenerator.generateProxyClass里面的细节 暂且不表
             */
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
            try {
                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());
            }
        }
    }
    //本地方法
     private static native Class<?> defineClass0(ClassLoader loader, String name, byte[] b, int off, int len);
       
}
  1. 查看defineClass0产生的类
    defineClass0是本地方法 无法查看实现,因此把 **byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);**产生的字节码写到文件中,然后反编译查看
public class ProxyUtil {
    public static void main(String[] args) {
       // ProxyGenerator.generateProxyClass()
    }
    public static void generateClassFile(Class clazz,String proxyName){
        byte[] fileBytes = ProxyGenerator.generateProxyClass(proxyName, new Class[]{clazz});
        URL resource = clazz.getResource("");
        String path = "D://";
        FileOutputStream out = null;
        try {
             out = new FileOutputStream(path + proxyName + ".class");
            out.write(fileBytes);
            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

生成的文件:

import com.sun.proxy..Proxy0;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Proxy0 {
    private static Method m1;
    private static Method m6;
    private static Method m3;
    private static Method m2;
    private static Method m7;
    private static Method m11;
    private static Method m13;
    private static Method m0;
    private static Method m8;
    private static Method m12;
    private static Method m5;
    private static Method m10;
    private static Method m4;
    private static Method m9;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final InvocationHandler getInvocationHandler(Object var1) throws IllegalArgumentException {
        try {
            return (InvocationHandler)super.h.invoke(this, m6, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String sayHello(String var1) throws  {
        try {
            return (String)super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final Class getProxyClass(ClassLoader var1, Class[] var2) throws IllegalArgumentException {
        try {
            return (Class)super.h.invoke(this, m7, new Object[]{var1, var2});
        } catch (RuntimeException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final Class getClass() throws  {
        try {
            return (Class)super.h.invoke(this, m11, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void notifyAll() throws  {
        try {
            super.h.invoke(this, m13, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void wait() throws InterruptedException {
        try {
            super.h.invoke(this, m8, (Object[])null);
        } catch (RuntimeException | InterruptedException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void notify() throws  {
        try {
            super.h.invoke(this, m12, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final Object newProxyInstance(ClassLoader var1, Class[] var2, InvocationHandler var3) throws IllegalArgumentException {
        try {
            return (Object)super.h.invoke(this, m5, new Object[]{var1, var2, var3});
        } catch (RuntimeException | Error var5) {
            throw var5;
        } catch (Throwable var6) {
            throw new UndeclaredThrowableException(var6);
        }
    }

    public final void wait(long var1) throws InterruptedException {
        try {
            super.h.invoke(this, m10, new Object[]{var1});
        } catch (RuntimeException | InterruptedException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final boolean isProxyClass(Class var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void wait(long var1, int var3) throws InterruptedException {
        try {
            super.h.invoke(this, m9, new Object[]{var1, var3});
        } catch (RuntimeException | InterruptedException | Error var5) {
            throw var5;
        } catch (Throwable var6) {
            throw new UndeclaredThrowableException(var6);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m6 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getInvocationHandler", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.sun.proxy.$Proxy0").getMethod("sayHello", Class.forName("java.lang.String"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m7 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getProxyClass", Class.forName("java.lang.ClassLoader"), Class.forName("[Ljava.lang.Class;"));
            m11 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getClass");
            m13 = Class.forName("com.sun.proxy.$Proxy0").getMethod("notifyAll");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            m8 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait");
            m12 = Class.forName("com.sun.proxy.$Proxy0").getMethod("notify");
            m5 = Class.forName("com.sun.proxy.$Proxy0").getMethod("newProxyInstance", Class.forName("java.lang.ClassLoader"), Class.forName("[Ljava.lang.Class;"), Class.forName("java.lang.reflect.InvocationHandler"));
            m10 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait", Long.TYPE);
            m4 = Class.forName("com.sun.proxy.$Proxy0").getMethod("isProxyClass", Class.forName("java.lang.Class"));
            m9 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait", Long.TYPE, Integer.TYPE);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

生成的代理类$Proxy0继承自Proxy, Proxy有个属性InvocationHandler. P r o x y 0 I n v o c a t i o n H a n d l e r P r o x y . n e w P r o x y I n s t a n c e [ I n v o c a t i o n H a n d l e r ] Proxy0类中方法的实现都是调用InvocationHandler中的方法。Proxy.newProxyInstance()时将[持有目标类的InvocationHandler]注入给**代理类 Proxy0**. 而代理类$Proxy0执行方法时,会调用super.h.invoke(this, m3, new Object[]{var1});


    public final String sayHello(String var1) throws  {
        try {
	        //super.h 即MyInvocationHandler
	        //.invoke()会调用MyInvocationHandler的invoke() 在这里我们是反射调用了target的方法,在其前后可以加上增强
            return (String)super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

产生的代理类

cglib动态代理

是封装了asm字节码的框架,性能比jdk动态代理要好,且可以代理没有接口的方法

实现1

//目标类
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name){
        System.out.println("你好啊:"+name);
        return "ok";
    }
}

public class MyCglibProxy implements MethodInterceptor {

    //持有对目标类的引用
    private Object target;
public MyCglibProxy(Object target ){
        this.target = target;

}

    /**
     * 创建代理实例
     * @param target
     * @return
     */
    public Object getInstance(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        // 设置回调 
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }

    /**
     * 实现MethodInterceptor接口要重写的方法。
     * 回调方法
     */
    public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
        System.out.println("事务开始。。。");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("事务结束。。。");
        return result;
    }
}

public class TestCglib {

    public static void main(String[] args) {

		// cglib 提供的property 可以将生成的字节码输出       
		System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D://cglib-code");

        MyCglibProxy cglib = new MyCglibProxy(new HelloServiceImpl());
        HelloServiceImpl helloServiceImplProxy = (HelloServiceImpl)cglib.getInstance();
        helloServiceImplProxy.sayHello("臧三");
    }
}

生成的字节码分为cglib本身类的字节码 和代理类的字节码

//生成了HelloServiceImpl的子类。实现了增强
public class HelloServiceImpl$$EnhancerByCGLIB$$86103d6 extends HelloServiceImpl implements Factory {

...

    final String CGLIB$sayHello$0(String var1) {
        return super.sayHello(var1);
    }

    public final String sayHello(String var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$sayHello$0$Method, new Object[]{var1}, CGLIB$sayHello$0$Proxy) : super.sayHello(var1);
    }

...

实现2

//目标类
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name){
        System.out.println("你好啊:"+name);
        return "ok";
    }
}

public class MyCglibProxy implements MethodInterceptor {

    //持有对目标类的引用
    private Class clazz;

    /**
     * 创建代理实例
     * @param target
     * @return
     */
    public Object getInstance(Class clazz){
        this.clazz= clazz;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        // 设置回调 
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }

    /**
     * 实现MethodInterceptor接口要重写的方法。
     * 回调方法
     */
    public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
        System.out.println("事务开始。。。");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("事务结束。。。");
        return result;
    }
}

public class TestCglib {

    public static void main(String[] args) {

		// cglib 提供的property 可以将生成的字节码输出       
		System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D://cglib-code");

        MyCglibProxy cglib = new MyCglibProxy(HelloServiceImpl.class);
        HelloServiceImpl helloServiceImplProxy = (HelloServiceImpl)cglib.getInstance();
        helloServiceImplProxy.sayHello("臧三");
    }
}

区别: 实现1 只能实现代理具体类,无法实现代理接口 ;实现2都可以。

注意: 代理接口时,需要在MyMethodIntercpter的intercept()方法中,不调用 super.invokSuper(),而是自己实现

== 但按照实现2 ,并且不调用父类方法,自己实现intercept 为什么会报 Cannot subclass final class class java.lang.Class呢==

cglib注意点

类不能final 报错,final修饰的方法,不会被增强,只执行该类
如果目标类是接口,由于它没有实现,所以不能在invoke()方法中调用父类的实现,要改成自己的实现

cglib 可以bean copy,性能不错,但不能map和实体间拷贝

BeanCopier使用ASM字节码生成技术,性能会非常好

常见的bean拷贝

jdk动态代理和cglib动态代理的区别

  1. 原理上的区别
    jdk动态代理: 是jdk通过反射生成一个实现了目标接口的类,是通过调用InvocationHandler来调用具体方法的 同时可以实现前置、后置增强
    cglib动态代理 cglib是在asm框架上封装的一个类库,它是通过生成目标类的子类,实现代理的。核心是实现了MethodInterceptor,实现了MethodInterceptor的interceptor,会在这里增强。
  2. 性能上 jdk1.6之前cglib比jdk的好很多,后来到1.8 差距在缩小 - [有时间可查资料 ] 具体哪个更好 不清楚
  3. spring上的使用 有接口的会用jdk 没接口的会用cglib
  4. 短板 jdk动态代理中的目标类 必须实现接口。cglib不用
    cglib不能对final修饰的方法进行代理,如果对final的类代理 就会报错

Spring AOP,AspectJ, CGLIB 有点晕

Spring AOP,AspectJ, CGLIB 有点晕
解释的很清楚

Spring AOP的源码分析

有AspectJ风格的springaop来说
需要导入

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

例子

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
    @Bean
    public FooService fooService() {
        return new FooService();
    }
    @Bean
    public MyAspect myAspect() {
        return new MyAspect();
    }
}
//Where {@code FooService} is a typical POJO component
public class FooService {
    // various methods
}
//{@code MyAspect} is an
// * {@code @Aspect}-style aspect
@Aspect
public class MyAspect {
    @Before("execution(* FooService+.*(..))")
    public void advice() {
        // advise FooService methods as appropriate
    }
}

以上是EnableAspectJAutoProxy注解上的例子.核心是EnableAspectJAutoProxy

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

   /**
    * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
    * to standard Java interface-based proxies. The default is {@code false}.
    */
   boolean proxyTargetClass() default false;

}

在这里插入图片描述
核心是:
@EnableAspectJAutoProxy会给容器中导入AbstractAutoProxyCreator的BeanPostProcessor的bean后处理器;
在实例化bean时 会对每个bean都执行一遍所有的bean后处理器,逐一增强,从而实现增强逻辑

初始化AbstractAutoProxyCreator

  1. @EnableAspectJAutoProxy 注入了AspectJAutoProxyRegistrar组件
	@Import(AspectJAutoProxyRegistrar.class)
	public @interface EnableAspectJAutoProxy {
	}
  1. AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,该接口是用在@Configuration注解中可以由@Import导入。
    在这里插入图片描述
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
	//最后调用了AopConfigUtils.registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
  1. AnnotationAwareAspectJAutoProxyCreator加载到BeanFacotry中,也就完成了将AOP代理的Bean后处理器
	AopConfigUtils.registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	//放在容器中
	this.beanDefinitionMap.put(beanName, beanDefinition);
	this.beanDefinitionNames.add(beanName);

AbstractAutoProxyCreator 的增强

  1. 接下来 是 AbstractAutoProxyCreator—>BeanPostProcessor来实现sping aop 的增强,在调用bean本身之前委托给指定的拦截器。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

	/**
	 * Create a proxy with the configured interceptors if the bean is
	 * identified as one to proxy by the subclass.
	 * @see #getAdvicesAndAdvisorsForBean
	 */
	@Override
	//1 bean后处理器 在初始化后调用postProcessAfterInitialization
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				//1-1 返回处理之后的bean 并完成了增强[如果需要的话]
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
	//1-1 返回处理之后的bean 并完成了增强[如果需要的话]
	wrapIfNecessary(){
		// Create proxy if we have advice.
		
		//获取增强Advisor的集合。具体增强逻辑暂且不表 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		// 1-1-1 获取目标类上的所有增强
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//1-1-2 产生代理对象
			Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
	}
		
	// 1-1-1 获取目标类上的所有增强	
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
	
	//通过实例的ProxyFactory 获取代理对象
	//1-1-2 产生代理对象
	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		//由默认的aop代理工厂DefaultAopProxyFactory
		//1-1-2-1 构建ProxyFactory工厂实例
		return proxyFactory.getProxy(getProxyClassLoader());
	}
	
	//1-1-2-1 构建ProxyFactory工厂实例
	public class DefaultAopProxyFactory{
		public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
			if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
				Class<?> targetClass = config.getTargetClass();
				if (targetClass == null) {
					throw new AopConfigException("TargetSource cannot determine target class: " +
							"Either an interface or a target is required for proxy creation.");
				}
				if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
					return new JdkDynamicAopProxy(config);
				}
				//class ObjenesisCglibAopProxy extends CglibAopProxy 
				return new ObjenesisCglibAopProxy(config);
			}
			else {
				return new JdkDynamicAopProxy(config);
			}
		}
	}
	
	class CglibAopProxy implements AopProxy, Serializable {
		//1-1-2-2 从ProxyFactory工厂实例中获取代理类
		public Object getProxy(@Nullable ClassLoader classLoader) {

			// Configure CGLIB Enhancer...
			Enhancer enhancer = createEnhancer();
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			// fixedInterceptorMap only populated at this point, after getCallbacks call above
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
			this.advised.getConfiguration
			
			
		}
	}

以spring的@Tranaction注解为例窥探在spring中的使用

发布了13 篇原创文章 · 获赞 10 · 访问量 1632

猜你喜欢

转载自blog.csdn.net/navigator2015/article/details/104875643