Spring IOC 和 AOP 部分源码分析

IOC 容器初始化流程

ApplicationContext 容器的初始化流程主要由AbstractApplicationContext 类中的refresh() 方法实现.
大致过程为

  1. 为BeanFactory 对象执行后续处理 -
  2. 在上下文Context中注册bean
  3. 为bean注册拦截处理器(AOP相关)
  4. 初始化上下文消息
  5. 初始化事件多播
  6. 初始化主题资源
  7. 注册自定义监听器
  8. 实例化所有非lazy-init 的singleton 实例
  9. 发布相应事件

分析AbstractApplicationContext .refresh()

public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        this.prepareBeanFactory(beanFactory);

        try {
            // 加载配置中BeanFactory 无法处理的内容. 如:propertyplaceholder的加载
            this.postProcessBeanFactory(beanFactory);
            // 将上一步加载的内容,作为一个容器可以管理的bean对象注册到ApplicationContext中.
            // 底层实质是在将postProcessBeanFactory 中加载的内容包装成一个容器ApplicationContext 可以管理的bean对象
            this.invokeBeanFactoryPostProcessors(beanFactory);
            // 继续完成上一步的注册. 配置文件中的配置的bean 对象都创建并注册完成.
            this.registerBeanPostProcessors(beanFactory);
            
            // 初始化国际化消息源
            this.initMessageSource();
            // 注册事件多播监听. 如ApplicationEvent 事件. 
            this.initApplicationEventMulticaster();
            // 初始化主题资源
            this.onRefresh();
            // 创建注册监听器
            this.registerListeners();
            // 初始化配置中出现的所有的lazy-init=false 的bean 对象
            this.finishBeanFactoryInitialization(beanFactory);
            // 发布最终事件. 生命周期监听事件. spring 容器定义了生命周期接口,可以实现容器启动调用初始化,容器销毁之前调用回收资源.
            this.finishRefresh();
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }

            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }

    }
}

AOP 面向切面编程

面向切面编程,底层原理是动态代理实现.
如果切面策略目标有接口实现,使用JDK动态代理技术;无接口则使用CGLIB技术生成动态代理.

分析JDKDynamicAopProxy.invoke()

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    // 获取目标源对象
    TargetSource targetSource = this.advised.targetSource;
    Object target = null;

    Boolean var9;
    try {
        if (this.equalsDefined || !AopUtils.isEqualsMethod(method)) {
            if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                Integer var19 = this.hashCode();
                return var19;
            }

            if (method.getDeclaringClass() == DecoratingProxy.class) {
                Class var18 = AopProxyUtils.ultimateTargetClass(this.advised);
                return var18;
            }
            // 定义返回结果数据的引用
            Object retVal;
            if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
                return retVal;
            }

            if (this.advised.exposeProxy) {
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            // 获取目标对象的类对象  
            target = targetSource.getTarget();
            Class<?> targetClass = target != null ? target.getClass() : null;
            // 获取代理需要在目标方法执行前后,切入的拦截器链.
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            if (chain.isEmpty()) {
                // 如果拦截器链为空即代理对象没有需要切入的拦截器,则执行目标对象中的方法.
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            } else {
                // 创建一个执行器,加入拦截信息,并按照顺序执行拦截代码和目标对象中的方法.
                MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // 按照顺序执行拦截代码和目标对象中的方法.
                retVal = invocation.proceed();
            }

            // 获取目标对象中方法的返回结果类型.  
            Class<?> returnType = method.getReturnType();
            if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                retVal = proxy;
            } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
            }

            Object var13 = retVal;
            return var13;
        }

        var9 = this.equals(args[0]);
    } finally {
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }

        if (setProxyContext) {
            AopContext.setCurrentProxy(oldProxy);
        }

    }

    return var9;
}

JDKDynamicAopProxy.invoke()中用到的重要方法

List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
如果拦截器链为空即代理对象没有需要切入的拦截器,则执行目标对象中的方法.

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
    // 方法匹配信息 获取spring容器中的缓存
    AdvisedSupport.MethodCacheKey cacheKey = new AdvisedSupport.MethodCacheKey(method);
    // 从已知缓存中 获取方法缓存匹配信息
    List<Object> cached = (List)this.methodCache.get(cacheKey);
    if (cached == null) {
        // 缓存中没有则查询代理对象需要执行的拦截信息
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
        // 保存缓存数据
        this.methodCache.put(cacheKey, cached);
    }

    return cached;
}

MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
按照顺序执行拦截代码和目标对象中的方法.

public Object proceed() throws Throwable {
    // 开始执行代理方法。 包含通知方法和目标对象中的真实方法。
    // 判断当前代理是否还有需要执行通知。 如果没有通知, 执行目标代码。  
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return this.invokeJoinpoint();
    } else {
        Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
            return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
        } else {
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值