zoukankan      html  css  js  c++  java
  • Spring Boot源码(八):Spring AOP源码

    关于spring aop的应用参见:Spring AOP-基于@AspectJ风格

    spring在初始化容器时就会生成代理对象:

     关于创建bean的源码参见:Spring Boot源码(六):Bean的创建详解

    我们进入createBean()的doCreateBean()方法:

     其中的initializeBean():

    其中的applyBeanPostProcessorsBeforeInitialization():

    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            for (BeanPostProcessor processor : getBeanPostProcessors()) {
                Object current = processor.postProcessAfterInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }

    此方法是拿到各种各样的后置处理器,去处理对象。

    再次加上条件断点:

     第5个是我们处理aop的后置处理器。如果我们没有使用aop,那就没有它。

     进入此类AbstractAutoProxyCreator的方法:

    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
            if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }

    wrapIfNecessary()方法:

     进入createProxy()方法:

     

     

    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);
                }
                return new ObjenesisCglibAopProxy(config);
            }
            else {
                return new JdkDynamicAopProxy(config);
            }
        }

    如果该类实现接口,用jdk代理,否则使用cglib代理,默认是jdk代理。

    再来看getProxy():

     它有两个实现类:

     JdkDynamicAopProxy#getProxy()

    public Object getProxy(@Nullable ClassLoader classLoader) {
            if (logger.isTraceEnabled()) {
                logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
            }
            Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
            findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
            return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
        }

    最后一行就是jdk代理的代码了。可见JDK动态代理

    附debug流程图:

  • 相关阅读:
    【Android Developers Training】 73. 布局变化的动画
    【Android Developers Training】 72. 缩放一个视图
    【Android Developers Training】 71. 显示翻牌动画
    svn更改地址怎么办
    python学习手册
    failed to bind pixmap to texture
    Ubuntu 12.04安装Google Chrome
    svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码
    重设SVN 的GNOME keyring [(null)] 的密码
    Nginx + uWSGI + web.py 搭建示例
  • 原文地址:https://www.cnblogs.com/SunSAS/p/12327960.html
Copyright © 2011-2022 走看看