Spring Framework源码地址:https://github.com/spring-projects/spring-framework
从目录结构可以看出整个Spring框架都遵从模块化设计的思路,总共分为20多个模块,如下图所示:
1.Spring的组成部分 从上图可以看出:
Spring主要分为五个部分:
1、测试模块:主要实现了Spring的Junit等测试框架。
2、Spring核心容器:里面都是Spring框架实现的基础 ,主要包括了spring-beans、spring-core、spring-context 等三个核心基础模块。
3、Spring Data模块:主要实现了包括Spring支持各种ORM框架,如JDBC Template、JPA、Mybatis等的集成;还包括了Spring集成Marshalling XML的处理模块;以及对Spring包括声明式与编程式事务的支持。
4、Spring核心功能扩展模块:主要在Spring核心模块的基础上,实现了包括AOP 、对象绑定、i18n、类型转换、事件、消息等框架机制的支持。
5、Spring Web模块:主要实现了Spring对Web的支持,如SpringMVC 、Webservice等的支持。
2.Spring 核心容器 Spring容器 的所有实现都基于Spring核心模块的实现,所以下文我主要基于Spring核心模块的核心代码实现做分析:
2.1 spring-beans模块: spring-beans模块提供 BeanFactory,工厂模式 的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。
下图是BeanFactory的层次结构如下:
从上图可以看出:BeanFactory为顶层的工厂接口,定义了获取单个Bean实例特征的方法,其下有
Spring对于Jndi类型的Bean工厂的直接实现;
AutowireCapableBeanFactory 定义了自动装载Bean一系列接口 ,为Spring容器实现自动装载功能 提供支持;
HierarchicalBeanFactory为BeanFactory提供层级关系,一个应用中可以存在多个BeanFactory,该类即为多个BeanFactory提供了层级关系,定义了获取父BeanFactory与当前层次BeanFactory是否包含某个Bean实例的方法;
ListableBeanFactory定义了获取Spring容器中所有某类(全部)Bean实例的方法。
2.1.1 DefaultListableBeanFactory自动装载bean AutowireCapableBeanFactory层次结构图如下:
AbstractAutowireCapableBeanFactory提供了可自动装配的Bean Factory的默认实现;
DefaultListableBeanFactory 为可自动装载的ConfigurableListableBeanFactory实现,该BeanFactory既满足可列出所有Bean的同时,又可以实现自动装配;
XmlBeanFactory为Spring容器提供的从xml文件中读取BeanDefinition 为DefaultListableBeanFactory的一种实现,目前在Spring Framework的最新版本中已不推荐使用。其中HierarchicalBeanFactory和ListableBeanFactory的实现关系与AutowireCapableBeanFactory相类似。
最终,DefaultListableBeanFactory同时实现了三种类型的BeanFactory的接口 。所以,下文主要以DefaultListableBeanFactory为例做Spring BeanFactory的实现分析:
从上图可以看出:DefaultListableBeanFactory中以线程安全ConcurrentHashMap容器存储了Spring容器中所有Bean的定义与beanName的键值对 与缓存了单例的Bean实例 ,以此来实现满足三种条件的BeanFactory;
Spring获取Bean实例时首先会从缓存中去取bean 实例,如果取不到,则创建实例 ,下面主要分析BeanFactory创建Bean实例的方法:
2.1.2 Spring容器获取Bean的步骤
1.先通过bean的Name查找缓存是否存在该实例,如果存在,则直接返回,不存在,则创建实例,
2.创建bean实例的过程为先从beanDefinition的map中取出BeanDefinnition,生成一个实例或cglib代理,注入依赖成员变量,执行初始化等方法,放入缓存 ,最终运行类型转换,返回给调用者一个bean的实例。
protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null ; if (mbd.isSingleton()) { instanceWrapper = this .factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null ) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class ) { mbd.resolvedTargetType = beanType; } synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed" , ex); } mbd.postProcessed = true ; } } boolean earlySingletonExposure = (mbd.isSingleton() && this .allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references" ); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed" , ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false ); if (earlySingletonReference != null ) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this .allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example." ); } } } } try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature" , ex); } return exposedObject; }
2.2 spring-core模块: 模块提供了框架的基本组成部分,包括IOC 和依赖注入功能,其中主要提供了三种注入方式,按bean的名称、构造函数、类型来自动装载 。
2.2.1依赖注入实现思路:通过反射注入到目标bean中
查找依赖 ,从Spring容器中取依赖的类
返回依赖类的实例
并转换类型后,通过反射注入到目标bean的实例 中。
2.3 spring-context模块: context模块建立在由core和 beans 模块的基础上建立起来的,它以一种类似于JNDI注册的方式访问对象。Context模块继承自Bean模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文 (比如,通过Servelet容器 )等功能。Context模块也支持Java EE的功能,比如EJB、JMX和远程调用等。
ApplicationContext接口是Context模块的焦点。 spring-context-support提供了对第三方库集成到Spring上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。
2.3.1 一般采用ApplicationContext来获取bean实例 我们平时使用获取Bean实例 往往不会直接通过BeanFactory获取,是通过ApplicationContext来进行获取的。
2.3.2 ApplicationContext三种实现 从上图可以看出,Spring ApplicationContext总共提供了三种基础类型的实现
ClassPathXmlApplicationContext(从classpath下spring配置文件,最常用 )
FileSystemXmlApplicationContext(从文件系统中读取spring配置文件)
AnnotationConfigReactiveWebApplicationContext(基于注解配置读入)来生成对应的ApplicationContext
这也是整个Spring容器的初始化 入口。下面方法是Spring容器的创建刷新的refresh方法:
public void refresh () throws BeansException, IllegalStateException { synchronized (this .startupShutdownMonitor) { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); } } }
2.3.3 Spring创建容器的过程 从上面代码可以看出,Spring初始化容器的过程为:
1、加载配置文件(xml或注解类)
2、prepareRefresh方法加载上下文环境的Properties和准备Spring的上下文环境
3、obtainFreshBeanFactory生成BeanFactory
4、prepareBeanFactory为上一步生成的BeanFactory 设置ClassLoader、callbacks(回调上下文)、ApplicationContextAwareProcessor(Spring生成Bean的初始化处理类)、依赖类、环境变量等信息
5、postProcessBeanFactory某些子类实现对BeaFactory的初始化后置逻辑处理
6、invokeBeanFactoryPostProcessors执行第4步设置的BeanFactoryPostProcessor对BeanFactory的初始化后置逻辑处理、BeanDefinitionRegistryPostProcessor实现向BeanFactory执行加入RootBeanDefinition等操作
7、registerBeanPostProcessors方法在BeanFactory注册Bean生成的BeanPostProcessor(拦截Bean的创建)
8、initMessageSource方法为Spring上下文初始化MessageSource
9、initApplicationEventMulticaster方法为Spring的Context设置ApplicationEventMulticaster,提供BeanFactory管理ApplicationListener个数及广播事件的类
10、onRefresh方法为Spring上下文注册一些特殊的Bean
11、registerListeners方法在Spring容器中注册所有的ApplicationListener
12、finishBeanFactoryInitialization初始化所有的非懒加载的Bean,注册到Spring容器 中
13、finishRefresh方法完成Spring容器的初始化操作,清空一些资源、发布Spring上下文的ContextRefreshedEvent事件
14、resetCommonCaches方法清空一些初始化缓存
详情请看此txt
Spring容器的refresh()【创建刷新】; 1 、prepareRefresh()刷新前的预处理; 1 )、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法; 2 )、getEnvironment().validateRequiredProperties();检验属性的合法等 3 )、earlyApplicationEvents= new LinkedHashSet<ApplicationEvent>();保存容器中的一些早期的事件; 2 、obtainFreshBeanFactory();获取BeanFactory; 1 )、refreshBeanFactory();刷新【创建】BeanFactory; 创建了一个this.beanFactory = new DefaultListableBeanFactory(); 设置id; 2 )、getBeanFactory();返回刚才GenericApplicationContext创建的BeanFactory对象; 3 )、将创建的BeanFactory【DefaultListableBeanFactory】返回; 3 、prepareBeanFactory(beanFactory);BeanFactory的预准备工作(BeanFactory进行一些设置); 1 )、设置BeanFactory的类加载器、支持表达式解析器... 2 )、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】 3 )、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx; 4 )、注册可以解析的自动装配;我们能直接在任何组件中自动注入: BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext 5 )、添加BeanPostProcessor【ApplicationListenerDetector】 6 )、添加编译时的AspectJ; 7 )、给BeanFactory中注册一些能用的组件; environment【ConfigurableEnvironment】、 systemProperties【Map<String, Object>】、 systemEnvironment【Map<String, Object>】 4 、postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作; 1 )、子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置 ======================以上是BeanFactory的创建及预准备工作================================== 5 、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor的方法; BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的; 两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor 1 )、执行BeanFactoryPostProcessor的方法; 先执行BeanDefinitionRegistryPostProcessor 1 )、获取所有的BeanDefinitionRegistryPostProcessor; 2 )、看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、 postProcessor.postProcessBeanDefinitionRegistry(registry ) 3 )、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor; postProcessor.postProcessBeanDefinitionRegistry(registry ) 4 )、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors; postProcessor.postProcessBeanDefinitionRegistry(registry ) 再执行BeanFactoryPostProcessor的方法 1 )、获取所有的BeanFactoryPostProcessor 2 )、看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、 postProcessor.postProcessBeanFactory() 3 )、在执行实现了Ordered顺序接口的BeanFactoryPostProcessor; postProcessor.postProcessBeanFactory() 4 )、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor; postProcessor.postProcessBeanFactory() 6 、registerBeanPostProcessors(beanFactory);注册BeanPostProcessor(Bean的后置处理器)【 intercept bean creation】 不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的 BeanPostProcessor、 DestructionAwareBeanPostProcessor、 InstantiationAwareBeanPostProcessor、 SmartInstantiationAwareBeanPostProcessor、 MergedBeanDefinitionPostProcessor【internalPostProcessors】、 1 )、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级 2 )、先注册PriorityOrdered优先级接口的BeanPostProcessor; 把每一个BeanPostProcessor;添加到BeanFactory中 beanFactory.addBeanPostProcessor(postProcessor); 3 )、再注册Ordered接口的 4 )、最后注册没有实现任何优先级接口的 5 )、最终注册MergedBeanDefinitionPostProcessor; 6 )、注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是 applicationContext.addApplicationListener((ApplicationListener<?>) bean); 7 、initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析); 1 )、获取BeanFactory 2 )、看容器中是否有id为messageSource的,类型是MessageSource的组件 如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource; MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取; 3 )、把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale); 8 、initApplicationEventMulticaster();初始化事件派发器; 1 )、获取BeanFactory 2 )、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster; 3 )、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster 4 )、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入 9 、onRefresh();留给子容器(子类) 1 、子类重写这个方法,在容器刷新的时候可以自定义逻辑; 10 、registerListeners();给容器中将所有项目里面的ApplicationListener注册进来; 1 、从容器中拿到所有的ApplicationListener 2 、将每个监听器添加到事件派发器中; getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); 3 、派发之前步骤产生的事件; 11 、finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean; 1 、beanFactory.preInstantiateSingletons();初始化后剩下的单实例bean 1 )、获取容器中的所有Bean,依次进行初始化和创建对象 2 )、获取Bean的定义信息;RootBeanDefinition 3 )、Bean不是抽象的,是单实例的,是懒加载; 1 )、判断是否是FactoryBean;是否是实现FactoryBean接口的Bean; 2 )、不是工厂Bean。利用getBean(beanName);创建对象 0 、getBean(beanName); ioc.getBean(); 1 、doGetBean(name, null, null, false); 2 、先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来) 从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256 );获取的 3 、缓存中获取不到,开始Bean的创建对象流程; 4 、标记当前bean已经被创建 5 、获取Bean的定义信息; 6 、【获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来;】 7 、启动单实例Bean的创建流程; 1 )、createBean(beanName, mbd, args); 2 )、Object bean = resolveBeforeInstantiation(beanName, mbdToUse);让BeanPostProcessor先拦截返回代理对象; 【InstantiationAwareBeanPostProcessor】:提前执行; 先触发:postProcessBeforeInstantiation(); 如果有返回值:触发postProcessAfterInitialization(); 3 )、如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4 ) 4 )、Object beanInstance = doCreateBean(beanName, mbdToUse, args);创建Bean 1 )、【创建Bean实例】;createBeanInstance(beanName, mbd, args); 利用工厂方法或者对象的构造器创建出Bean实例; 2 )、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName); 3 )、【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper); 赋值之前: 1 )、拿到InstantiationAwareBeanPostProcessor后置处理器; postProcessAfterInstantiation(); 2 )、拿到InstantiationAwareBeanPostProcessor后置处理器; postProcessPropertyValues(); =====赋值之前:=== 3 )、应用Bean属性的值;为属性利用setter方法等进行赋值; applyPropertyValues(beanName, mbd, bw, pvs); 4 )、【Bean初始化】initializeBean(beanName, exposedObject, mbd); 1 )、【执行Aware接口方法】invokeAwareMethods(beanName, bean);执行xxxAware接口的方法 BeanNameAware\BeanClassLoaderAware\BeanFactoryAware 2 )、【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); BeanPostProcessor.postProcessBeforeInitialization(); 3 )、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd); 1 )、是否是InitializingBean接口的实现;执行接口规定的初始化; 2 )、是否自定义初始化方法; 4 )、【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization BeanPostProcessor.postProcessAfterInitialization(); 5 )、注册Bean的销毁方法; 5 )、将创建的Bean添加到缓存中singletonObjects; ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息。。。。; 所有Bean都利用getBean创建完成以后; 检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated(); 12 、finishRefresh();完成BeanFactory的初始化创建工作;IOC容器就创建完成; 1 )、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor 默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor(); 加入到容器; 写一个LifecycleProcessor的实现类,可以在BeanFactory void onRefresh(); void onClose(); 2 )、 getLifecycleProcessor().onRefresh(); 拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh(); 3 )、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件; 4 )、liveBeansView.registerApplicationContext(this);
======总结=========== 1)、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息; 1)、xml注册bean; 2)、注解注册Bean;@Service、@Component、@Bean、xxx 2)、Spring容器会合适的时机创建这些Bean 1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中; 2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization(); 3)、后置处理器;BeanPostProcessor 1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能; AutowiredAnnotationBeanPostProcessor:处理自动注入 AnnotationAwareAspectJAutoProxyCreator:来做AOP功能; xxx…. 增强的功能注解: AsyncAnnotationBeanPostProcessor …. 4)、事件驱动模型; ApplicationListener;事件监听; ApplicationEventMulticaster;事件派发:
3. AOP 3.1 spring-aop模块: 首先,我们需要知道Spring的AOP的几个基本术语:
Spring AOP基本术语
名称
描述
Aspect(切面)
一个模块具有一组提供横切需求的 APIs。例如,一个日志模块为了记录日志将被 AOP 方面调用。应用程序可以拥有任意数量的方面,这取决于需求。
Join point(连接点)
程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
Advice(通知点)
特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”、“after”和“throws”通知。
Pointcut(切点)
这是一组一个或多个连接点,通知应该被执行
Introduction(引入)
引用允许你添加新方法或属性到现有的类中
Target object(目标对象)
被一个或者多个方面所通知的对象,这个对象永远是一个被代理对,也称为被通知对象
Weaving(织入点)
Weaving 把方面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时,类加载时和运行时完成
下面是Spring AOP的切点声明接口:
public interface Pointcut { ClassFilter getClassFilter () ; MethodMatcher getMethodMatcher () ; Pointcut TRUE = TruePointcut.INSTANCE; }
从上面可以看出Spring的切点实际上是一个定义了切点方法及类描述的描述实现类 。
那么Spring容器是如何初始化实现AOP的功能呢,要实现AOP功能有两种方式:
1、静态代理,生成的编译类就已经实现AOP代理类
2、动态代理,程序运行时动态地生成AOP代理类
3.2 动态代理 动态代理的特点
字节码随用随创建,随用随加载。
它与静态代理的区别也在于此。因为静态代理是字节码一上来就创建好,并完成加载。
装饰者模式就是静态代理的一种体现。
从上面的Spring容器初始化分析中,可以找到AbstractAutowireCapableBeanFactory类中
protected Object initializeBean (final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null ) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null ; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null ), beanName, "Invocation of init method failed" , ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
初始化Bean时,会触发Aware实现的方法,也会触发BeanPostProcessor实现的方法,其中在BeanPostProcessor的实现postProcessAfterInitialization方法中,完成初始化后,有一个AbstractAdvisingBeanPostProcessor的实现,这之中实现了Spring生成AOP的代理对象方法:
public Object postProcessAfterInitialization (Object bean, String beanName) { if (bean instanceof AopInfrastructureBean || this .advisor == null ) { return bean; } if (bean instanceof Advised) { Advised advised = (Advised) bean; if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) { if (this .beforeExistingAdvisors) { advised.addAdvisor(0 , this .advisor); } else { advised.addAdvisor(this .advisor); } return bean; } } if (isEligible(bean, beanName)) { ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName); if (!proxyFactory.isProxyTargetClass()) { evaluateProxyInterfaces(bean.getClass(), proxyFactory); } proxyFactory.addAdvisor(this .advisor); customizeProxyFactory(proxyFactory); return proxyFactory.getProxy(getProxyClassLoader()); } return bean; }
@Override 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); } }
从上图可以看出Spring实现AOP代理类的获取时,有两种实现
第一种基于Jdk的动态代理,Spring优先采用Jdk的动态代理实现 。
第二种基于Cglib的代理
3.3 AOP源码分析: * AOP原理:【看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?】 * @EnableAspectJAutoProxy; * 1 、@EnableAspectJAutoProxy是什么? * @Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar * 利用AspectJAutoProxyRegistrar自定义给容器中注册bean;BeanDefinetion * internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator * * 给容器中注册一个AnnotationAwareAspectJAutoProxyCreator; * * 2 、 AnnotationAwareAspectJAutoProxyCreator: * AnnotationAwareAspectJAutoProxyCreator * ->AspectJAwareAdvisorAutoProxyCreator * ->AbstractAdvisorAutoProxyCreator * ->AbstractAutoProxyCreator * implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware * 关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory * * AbstractAutoProxyCreator.setBeanFactory() * AbstractAutoProxyCreator.有后置处理器的逻辑; * * AbstractAdvisorAutoProxyCreator.setBeanFactory()-》initBeanFactory() * * AnnotationAwareAspectJAutoProxyCreator.initBeanFactory() * * * 流程: * 1 )、传入配置类,创建ioc容器 * 2 )、注册配置类,调用refresh()刷新容器; * 3 )、registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建; * 1 )、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor * 2 )、给容器中加别的BeanPostProcessor * 3 )、优先注册实现了PriorityOrdered接口的BeanPostProcessor; * 4 )、再给容器中注册实现了Ordered接口的BeanPostProcessor; * 5 )、注册没实现优先级接口的BeanPostProcessor; * 6 )、注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中; * 创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】 * 1 )、创建Bean的实例 * 2 )、populateBean;给bean的各种属性赋值 * 3 )、initializeBean:初始化bean; * 1 )、invokeAwareMethods():处理Aware接口的方法回调 * 2 )、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization() * 3 )、invokeInitMethods();执行自定义的初始化方法 * 4 )、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization(); * 4 )、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--》aspectJAdvisorsBuilder * 7 )、把BeanPostProcessor注册到BeanFactory中; * beanFactory.addBeanPostProcessor(postProcessor); * =======以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程======== * * AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBeanPostProcessor * 4 )、finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;创建剩下的单实例bean * 1 )、遍历获取容器中所有的Bean,依次创建对象getBean(beanName); * getBean->doGetBean()->getSingleton()-> * 2 )、创建bean * 【AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截,InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()】 * 1 )、先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建; * 只要创建好的Bean都会被缓存起来 * 2 )、createBean();创建bean; * AnnotationAwareAspectJAutoProxyCreator 会在任何bean创建之前先尝试返回bean的实例 * 【BeanPostProcessor是在Bean对象创建完成初始化前后调用的】 * 【InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的】 * 1 )、resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation * 希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续 * 1 )、后置处理器先尝试返回对象; * bean = applyBeanPostProcessorsBeforeInstantiation(): * 拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor; * 就执行postProcessBeforeInstantiation * if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } * * 2 )、doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;和3.6 流程一样; * 3 )、 * * * AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】 的作用: * 1 )、每一个bean创建之前,调用postProcessBeforeInstantiation(); * 关心MathCalculator和LogAspect的创建 * 1 )、判断当前bean是否在advisedBeans中(保存了所有需要增强bean) * 2 )、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean, * 或者是否是切面(@Aspect) * 3 )、是否需要跳过 * 1 )、获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】 * 每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor; * 判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true * 2 )、永远返回false * * 2 )、创建对象 * postProcessAfterInitialization; * return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下 * 1 )、获取当前bean的所有增强器(通知方法) Object[] specificInterceptors * 1 、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的) * 2 、获取到能在bean使用的增强器。 * 3 、给增强器排序 * 2 )、保存当前bean在advisedBeans中; * 3 )、如果当前bean需要增强,创建当前bean的代理对象; * 1 )、获取所有增强器(通知方法) * 2 )、保存到proxyFactory * 3 )、创建代理对象:Spring自动决定 * JdkDynamicAopProxy(config);jdk动态代理; * ObjenesisCglibAopProxy(config);cglib的动态代理; * 4 )、给容器中返回当前组件使用cglib增强了的代理对象; * 5 )、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程; * * * 3 )、目标方法执行 ; * 容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx); * 1 )、CglibAopProxy.intercept();拦截目标方法的执行 * 2 )、根据ProxyFactory对象获取将要执行的目标方法拦截器链; * List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); * 1 )、List<Object> interceptorList保存所有拦截器 5 * 一个默认的ExposeInvocationInterceptor 和 4 个增强器; * 2 )、遍历所有的增强器,将其转为Interceptor; * registry .getInterceptors(advisor); * 3 )、将增强器转为List<MethodInterceptor>; * 如果是MethodInterceptor,直接加入到集合中 * 如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor; * 转换完成返回MethodInterceptor数组; * * 3 )、如果没有拦截器链,直接执行目标方法; * 拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制) * 4 )、如果有拦截器链,把需要执行的目标对象,目标方法, * 拦截器链等信息传入创建一个 CglibMethodInvocation 对象, * 并调用 Object retVal = mi.proceed(); * 5 )、拦截器链的触发过程; * 1 )、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1 大小一样(指定到了最后一个拦截器)执行目标方法; * 2 )、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行; * 拦截器链的机制,保证通知方法与目标方法的执行顺序;
总结:
1)、@EnableAspectJAutoProxy 开启AOP功能
2)、@EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
4)、容器的创建流程:
1)、registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
2)、finishBeanFactoryInitialization()初始化剩下的单实例bean
1)、创建业务逻辑组件和切面组件
2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
3)、组件创建完之后,判断组件是否需要增强
是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
5)、执行目标方法:
1)、代理对象执行目标方法
2)、CglibAopProxy.intercept() ;
1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
3)、效果:
正常执行:前置通知-》目标方法-》后置通知-》返回通知
出现异常:前置通知-》目标方法-》后置通知-》异常通知