美文网首页Spring
Spring | 0.9 AOP

Spring | 0.9 AOP

作者: 不一样的卡梅利多 | 来源:发表于2020-05-12 17:30 被阅读0次

    AOP

    核心功能:将业务代码与非业务代码连接到一起,并且还需要集成到bean 容器中

    核心类视图

    AOP 核心类.png

    AOP 与beans 集成

    spring 创建ProxyFactoryBean 调用时序
    1. spring读取配置 ,实例化ProxyFactoryBean,并且设置setProxyInterfaces(String[] interfaceNames)

    1. ProxyFactoryBean 创建完成后,调用setBeanFactory(BeanFactory beanFactory),afterPropertiesSet()

    2. 由于ProxyFactoryBean 是一个FactoryBean ,还需要依据继续创建对象 FactoryBean.getObject()

    FactoryBean.getObject 实现

    public Object getObject() throws BeansException {
            if (this.singleton) {
                // Return singleton
                return this.singletonInstance;
            }
            else {
                // Create new interface
                return createInstance();
            }
        }
    
    private Object createInstance() {
            refreshInterceptorChain();
            AopProxy proxy = new AopProxy(this);
            return AopProxy.getProxy(getClass().getClassLoader(), proxy);
        }
    

    refreshInterceptorChain: 实例化 MethodPointcut bean,并且创建InvokerInterceptor

    AopProxy.getProxy:依据配置创建动态代理对象。生成的代理对象调方法调用逻辑走AopProxy.invoke 方法,委派给MethodInvocationImpl 实现,对方法调用添加配置的一系列拦截器。实现了代码动态链接功能。

        public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        
            // Create a new invocation object
            // TODO refactor into InvocationFactory?
            MethodInvocationImpl invocation = new MethodInvocationImpl(proxy, config.getTarget(), 
                                        method.getDeclaringClass(), //?
                                        method, args,
                                        this.config.getMethodPointcuts(), // could customize here
                                        this.config.getAttributeRegistry());
            
            if (this.config.getExposeInvocation()) {
                // Make invocation available if necessary
                AopContext.setCurrentInvocation(invocation);
            }
            
            try {
                if (EQUALS_METHOD.equals(invocation.getMethod())) {
                    // What if equals throws exception!?
                    logger.debug("Intercepting equals() method in proxy");
                    return invocation.getMethod().invoke(this, invocation.getArguments());
                }
                
                Object retVal = invocation.invokeNext();
                if (retVal != null && retVal == invocation.getInvokedObject()) {
                    // Special case: it returned this
                    // Note that we can't help if the target sets
                    // a reference to itself in another returned object
                    logger.debug("Replacing 'this' with reference to proxy");
                    retVal = proxy;
                }
                return retVal;
            }
            finally {
                if (this.config.getExposeInvocation()) {
                    AopContext.setCurrentInvocation(null);
                }
            
                //if (logger.isDebugEnabled()) {
                //  logger.debug("Processed invocation [" + invocation + "]");
                //}
            }
        }
    

    Spring 专题

    相关文章

      网友评论

        本文标题:Spring | 0.9 AOP

        本文链接:https://www.haomeiwen.com/subject/fzqinhtx.html