一. AOP功能测试

①. pom.xml 依赖导入

②. 目标类

③. 切面类

④. 配置类

⑤. 测试类

二. AOP原理-@EnableAspectJAutoProxy

AOP原理:【看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?】@EnableAspectJAutoProxy;

  1、@EnableAspectJAutoProxy是什么?
@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar组件
利用AspectJAutoProxyRegistrar将internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator后置处理器的BeanDefinetion的定义信息添加到BeanDefinitionRegistry中
只是注册定义信息并没创建AnnotationAwareAspectJAutoProxyCreator对象
例如,RootBeanDefinition beanDefinition = new RootBeanDefinition(AnnotationAwareAspectJAutoProxyCreator);
registry.registerBeanDefinition("internalAutoProxyCreator", beanDefinition);
2、 AnnotationAwareAspectJAutoProxyCreator的类结构信息:
AnnotationAwareAspectJAutoProxyCreator
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
现在我们关注这两个接口: AnnotationAwareAspectJAutoProxyCreator是后置处理器,另外一个怎么装配BeanFactory AbstractAutoProxyCreator.setBeanFactory()
AbstractAutoProxyCreator.有后置处理器的逻辑; AbstractAdvisorAutoProxyCreator.setBeanFactory()-》initBeanFactory() AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()

①. 给容器中导入AspectJAutoProxyRegistrar

②. 利用AspectJAutoProxyRegistrar自定义类给容器注册名为AnnotationAwareAspectJAutoProxyCreator的bean组件,BeanDefinetion

③. 给容器中注册一个AnnotationAwareAspectJAutoProxyCreator的bean组件

④. AnnotationAwareAspectJAutoProxyCreator继承关系

⑤. 关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory;因为①至③步骤只是注册了组件并没有创建AnnotationAwareAspectJAutoProxyCreator对象

a、AbstractAutoProxyCreator.setBeanFactory()

b、AbstractAutoProxyCreator.有后置处理器的逻辑

c、AbstractAdvisorAutoProxyCreator.setBeanFactory()-》initBeanFactory()

d、AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()

三. 创建和注册AnnotationAwareAspectJAutoProxyCreator组件的bean对象的过程

流程:
1)传入配置类,创建IOC容器
2)注册配置类,调用refresh();方法刷新容器
3)如何刷新:
registerBeanPostProcessors(beanFactory);
注册bean的后置处理器来方便拦截bean的创建
registerBeanPostProcessors方法里面调用registerBeanPostProcessors
registerBeanPostProcessors里面步骤:
1.获取IOC容器已经定义好的需要创建对象的所有的BeanPostProcessor
比如: 该@EnableAspectJAutoProxy注解只是将AnnotationAwareAspectJAutoProxyCreator后置处理器的BeanDefinition定义信息添加到BeanDefinitionRegistry中,但是还没创建其对应的对象 对应的代码:String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
2.给容器添加一些别的BeanPostProcessor
对应代码:beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
3.优先将实现了PriorityOrdered接口的BeanPostProcessor创建并注册到容器中 registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors)
4.将实现了Ordered接口的BeanPostProcessor创建并注册到容器中registerBeanPostProcessors(beanFactory, orderedPostProcessors);
5.最后将没实现优先级接口的BeanPostProcessor创建并注册到容器中 registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors)
3-5步的原码解释:
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest. // First, register the BeanPostProcessors that implement PriorityOrdered.
// Next, register the BeanPostProcessors that implement Ordered. 例子 AnnotationAwareAspectJAutoProxyCreator实现了 Ordered
// Now, register all regular BeanPostProcessors.
6.怎么创建和注册呢?
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class)--> doGetBean -->getSingleton(beanName,singletonFactory)-->this.singletonFactory.getObject()
---> 跳到createBean(beanName, mbd, args);创建对象-->doCreateBean(beanName, mbdToUse, args) 例如,创建internalAutoProxyCreator的后置处理器,其实类型是AnnotationAwareAspectJAutoProxyCreator
创建bean的过程:
1 创建Bean实例
2 populateBean:给bean的各种属性赋值
3 initializeBean:初始化bean:
过程:
1.invokeAwareMethods(),处理Aware接口的方法回调
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
} // 该步骤会执行AbstractAdvisorAutoProxyCreator#setBeanFactory方法,自动装配BeanFactory
2.applyBeanPostProcessorsBeforeInitialization():后置处理器的PostProcessorsBeforeInitialization方法
3.invokeInitMethods():执行自定义的初始化方法
4.applyBeanPostProcessorsAfterInitialization():后置处理器的PostProcessorsAfterInitialization方法
4 BeanPostProcessor(以AnnotationAwareAspectJAutoProxyCreator为例的bean)创建成功
7.把BeanPostProcessor注册到beanFactory中:
orderedPostProcessors.add(pp);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
执行PostProcessorRegistrationDelegate#registerBeanPostProcessors方法,调用 beanFactory.addBeanPostProcessor(postProcessor)---> this.beanPostProcessors.add(beanPostProcessor);
=========上面就是创建和注册AnnotationAwareAspectJAutoProxyCreator组件的bean全过程===========
AnnotationAwareAspectJAutoProxyCreator ========>InstantiationAwareBeanPostProcessor

①. 注册配置类,调用refresh()刷新容器

②. registerBeanPostProcessors(beanFactory),创建并注册bean的后置处理器来方便拦截bean的创建

③. 先获取ioc容器已经存在定义信息,但需要创建BeanPostProcessor后置处理器的对象

④. 将实现了Ordered接口的BeanPostProcessor,将其创建并注册到容器中registerBeanPostProcessors(beanFactory, orderedPostProcessors)

⑤. 创建internalAutoProxyCreator的后置处理器,类型是AnnotationAwareAspectJAutoProxyCreator的BeanPostProcessor

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class) --> doGetBean --> getSingleton-->singletonFactory.getObject()

--- > 跳到createBean(beanName, mbd, args)---> 创建对象-->doCreateBean(beanName, mbdToUse, args)

⑥. populateBean:属性赋值与其它bean的依赖注入

7. initializeBean:初始化操作

8. invokeAwareMethods():处理Aware接口的方法回调,自动装配BeanFactory

该步骤会执行AbstractAdvisorAutoProxyCreator#setBeanFactory方法,自动装配BeanFactory

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

把beanFactory设置到BeanPostProcessor的setBeanFactory方法中

AnnotationAwareAspectJAutoProxyCreator#initBeanFactory,创建aspectJAdvisorFactory 和 aspectJAdvisorsBuilder对象

9. applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) --> 后置处理器的 beanProcessor.postProcessBeforeInitialization(result, beanName)方法

10. invokeInitMethods(beanName, wrappedBean, mbd),执行自定义的初始化方法

11. applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) -->后置处理器的 beanProcessor.postProcessAfterInitialization(result, beanName)

12. 将BeanPostProcessor后置处理器对象创建完成后注册到beanPostProcessors中

1、registerBeanPostProcessors(beanFactory, orderedPostProcessors);

2、执行PostProcessorRegistrationDelegate#registerBeanPostProcessors方法,调用 beanFactory.addBeanPostProcessor(postProcessor);

private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}

3、this.beanPostProcessors.add(beanPostProcessor);

四. 业务bean和切面bean对象的创建

finishBeanFactoryInitialization(beanFactory);完成BeanFactory的初始化工作,就是创建剩下的单实例bean
1.遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
getBean(beanName);->doGetBean()->getSingleton()->singletonFactory.getObject();->createBean
2.注意第一步的createBean,它是有if条件的
首先是从缓存中获取当前bean,如果能获取到证明bean是之前被创建过的,直接使用
如果获取不到进入else语句,创建bean
这样就保证单实例的bean只会被创建一次,创建好的bean会被缓存起来
3.createBean();创建bean
[AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截,
因为它是InstantiationAwareBeanPostProcessor类,会调用postProcessBeforeInstantiation()方法]
AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean的实例
[BeanPostProcessor是在bean对象创建完成初始化前后调用的]
[InstantiationAwareBeanPostProcessor是在创建Bean实例之前,判断容器是否已经存在bean实例,若存在,则尝试使用用后置处理器为其创建一个代理对象]
这样的bean实例一般是通过以下方式创建的:
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP { //业务逻辑类加入容器中
@Bean
public MathCalculator calculator(){
return new MathCalculator();
} //切面类加入到容器中
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
若容器已存在bean实例,则通过AbstractAutowireCapableBeanFactory#createBean --> resolveBeforeInstantiation(beanName, mbdToUse)尝试使用用后置处理器为其创建一个代理对象;
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
解析resolveBeforeInstantiation(beanName, mbdToUse);
希望后置处理器在此返回一个代理对象,如果能返回就使用,如果不能就第二步
4.若容器不存在bean实例,执行doCreateBean(beanName, mbdToUse, args);这个是真正创建bean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException { // 创建 bean 实例
instanceWrapper = createBeanInstance(beanName, mbd, args); // bean 属性的填充
populateBean(beanName, mbd, instanceWrapper); // bean 初始化过程
exposedObject = initializeBean(beanName, exposedObject, mbd);
} protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { // 处理Aware接口的方法回调
invokeAwareMethods(beanName, bean); // 后置处理器前置方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); // 自定义的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd); // 后置处理器后置方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

在bean实例化之前 和 bean初始化之后有两次机会为其生成代理对象

第一次、具体是bean的实例化过程会走到Object bean = resolveBeforeInstantiation(beanName, mbdToUse)方法,使用后置处理器为bean目标方法生成代理类

五. 若容器中目标对象bean已经存在,则后置处理AnnotationAwareAspectJAutoProxyCreator尝试调用postProcessBeforeInstantiation()方法为目标对象bean创建proxy代理对象

AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用:
A、每一个bean创建之前,调用postProcessBeforeInstantiation();
关心MathCalculator和LogAspect的创建
1、判断当前bean是否在advisedBeans中,若为true,则为不代理
2、判断isInfrastructureClass方法检查Bean的类是否是Spring AOP的基础设施类,比如是否实现了特定的接口(如Advice、Pointcut等),或者是否是切面(@Aspect)
3、是否需要跳过
a、获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor;
判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
b、永远返回false

①. 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean

②. 判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true

六. 若容器中目标对象bean不存在,bean创建后执行AbstractAutowireCapableBeanFactory#initializeBean方法--->applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),

则后置处理AnnotationAwareAspectJAutoProxyCreator尝试调用postProcessAfterInitialization()为bean创建proxy代理对象

创建对象
B、postProcessAfterInitialization;return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下
1、获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
a、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
b、获取到能在bean使用的增强器。
c、给增强器排序
2、保存当前bean在advisedBeans中;
3、如果当前bean需要增强,创建当前bean的代理对象;
a、获取所有增强器(通知方法)
b、保存到proxyFactory
c、创建代理对象:Spring自动决定
JdkDynamicAopProxy(config);jdk动态代理;
ObjenesisCglibAopProxy(config);cglib的动态代理;
4、给容器中返回当前组件使用cglib增强了的代理对象;
5、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;

第二次,在bean的初始化过程中wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)也会提供使用后置处理器生成代理类

①. wrapIfNecessary()

②. 获取当前bean的所有增强器(通知方法) Object[] specificInterceptors

③. 保存当前bean在advisedBeans中

④. 如果当前bean需要增强,创建当前bean的代理对象

⑤. 给容器中返回当前组件使用cglib增强了的代理对象

⑥. 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程

七. 目标方法执行

目标方法执行;容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);
1、CglibAopProxy.intercept();拦截目标方法的执行
2、根据ProxyFactory对象获取将要执行的目标方法拦截器链;
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
a、List<Object> interceptorList保存所有拦截器 5
一个默认的ExposeInvocationInterceptor 和 4个增强器;
b、遍历所有的增强器,将其转为Interceptor;
registry.getInterceptors(advisor);
c、将增强器转为List<MethodInterceptor>;
如果是MethodInterceptor,直接加入到集合中
如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
转换完成返回MethodInterceptor数组; 3、如果没有拦截器链,直接执行目标方法;
拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
4、如果有拦截器链,把需要执行的目标对象,目标方法,
拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
并调用 Object retVal = mi.proceed();
5、拦截器链的触发过程;
a、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
b、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
拦截器链的机制,保证通知方法与目标方法的执行顺序;

①. 容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx)

②. CglibAopProxy.intercept();拦截目标方法的执行

③. 根据ProxyFactory对象获取将要执行的目标方法拦截器链

④. 如果没有拦截器链,直接执行目标方法

⑤. 如果有拦截器链,把需要执行的目标对象,目标方法

⑥. 拦截器链的触发过程

八. 目标方法执行

九. AOP-原理总结

总结:
1、 @EnableAspectJAutoProxy 开启AOP功能
2、 @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
3、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
4、容器的创建流程:
(1)、registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator后置处理器对象
(2)、finishBeanFactoryInitialization()初始化剩下的单实例bean
a、创建业务逻辑组件和切面组件过程中
b、若容器中的bean已存在,则使用AnnotationAwareAspectJAutoProxyCreator后置处理器尝试拦截bean组件为其创建一个proxy代理对象
c、若容器中的bean不已存在,组件创建完之后,再次使用AnnotationAwareAspectJAutoProxyCreator后置处理器尝试拦截bean组件为其创建一个proxy代理对象
判断组件是否需要增强
是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个proxy代理对象,可能是cglib,也可能是jdk; 5、执行目标方法:
(1)、代理对象执行目标方法
(2)、CglibAopProxy.intercept();
a、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
b、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
c、效果:
正常执行:前置通知-》目标方法-》返回通知-》后置通知
出现异常:前置通知-》目标方法-》异常通知-》后置通知

Spring底层AOP代码实现的更多相关文章

  1. Spring之AOP原理、代码、使用详解(XML配置方式)

    Spring 的两大核心,一是IOC,另一个是AOP,本博客从原理.AOP代码以及AOP使用三个方向来讲AOP.先给出一张AOP相关的结构图,可以放大查看. 一.Spring AOP 接口设计 1.P ...

  2. Spring 的 AOP 概述和底层实现

    Spring 的 AOP 概述和底层实现 1. 什么是 AOP AOP (Aspect Oriented Programing),即面向切面编程 AOP 采取横向抽取机制,取代了传统纵向继承体系重复性 ...

  3. 30个类手写Spring核心原理之AOP代码织入(5)

    本文节选自<Spring 5核心原理> 前面我们已经完成了Spring IoC.DI.MVC三大核心模块的功能,并保证了功能可用.接下来要完成Spring的另一个核心模块-AOP,这也是最 ...

  4. Spring 的AOP底层实现技术:JDK和CGLIB动态代理

    Spring 的AOP实现技术之JDK的动态代理技术实例: 接口:IUserService (Spring的AOP是动态AOP,实现技术:JDK提供的动态代理和cglib代理,cglib它可以为没有实 ...

  5. Spring 实践 -AOP

    Spring 实践 标签: Java与设计模式 AOP引介 AOP(Aspect Oriented Programing)面向切面编程采用横向抽取机制,以取代传统的纵向继承体系的重复性代码(如性能监控 ...

  6. spring(二) AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  7. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  8. Spring IOC AOP的原理 如果让你自己设计IOC,AOP如何处理(百度)

    百度的面试官问,如果让你自己设计一个IOC,和AOP,如何设计, 我把IOC的过程答出来了,但是明显不对, (1) IOC 利用了反射,自己有个id,classtype,hashmap,所有的功能都在 ...

  9. Spring框架第五篇之Spring与AOP

    一.AOP概述 AOP(Aspect Orient Programming),面向切面编程,是面向对象编程OOP的一种补充.面向对象编程是从静态角度考虑程序的结构,而面向切面编程是从动态角度考虑程序运 ...

  10. 08 Spring框架 AOP (一)

    首先我们先来介绍一下AOP: AOP(Aspect Orient Programming),面向切面编程,是面向对象编程OOP的一种补充.面向对象编程是从静态角度考虑程序的结构,面向切面编程是从动态的 ...

随机推荐

  1. 使用Ollama

    推荐 Ollama 本地运行大模型(LLM)完全指南 Ollama中文学习 应用 查看可支持的模型:https://ollama.com/library 查看运行中的模型 ollama ps 停止模型 ...

  2. jdk 5.0 新增的foreach循环(用于遍历集合、数组)

    使用 foreach 循环遍历集合元素 Java 5.0 提供了 foreach 循环迭代访问 Collection和数组. 遍历操作不需获取Collection或数组的长度,无需使用索引访问元素 ...

  3. 认识soui4js(第1篇)

    源代码:https://github.com/soui4js/soui4js soui4js是soui4+quickjs的结合体. soui4是一套c++ directui客户端开发框架,soui4j ...

  4. MySql中创建用户以及设置其操作权限

    以下设置针对MySql8+版本进行测试,低版本暂无测试. 以管理员身份CMD并定位到MySql安装的bin目录,然后执行命令mysql -u root -p登录到MySql,然后输入登录密码,登录成功 ...

  5. 【忍者算法】从扫雷游戏到矩阵操作:探索矩阵置零问题|LeetCode 73 矩阵置零

    从扫雷游戏到矩阵操作:探索矩阵置零问题 生活中的算法 想象你在玩扫雷游戏,当你点到一个地雷时,不仅这个格子会被标记,与它同行同列的格子也都会受到影响.或者想象一个办公室的座位表,如果某个位置发现了感染 ...

  6. Q:jar包启动脚本备份

    jarServer.sh #!/bin/bash #APP_NAME必须配置. cd `dirname $0` cd .. DEPLOY_DIR=`pwd` APP_HOME=$DEPLOY_DIR/ ...

  7. SuiteCRM 7.11.18 安装及汉化

    SuiteCRM 7.11.18 安装及汉化 sourceforge下载,github也有https://sourceforge.net/projects/suitecrm/files/SuiteCR ...

  8. 同事PPT又拿奖了?偷偷用这AI工具,3步做出老板狂赞的年度报告

    大家好,我是六哥,今天为大家分享一款PPT辅助神器,年底汇报必备神器!就是Napkin AI ! 这是一款超级酷的工具,它能把你写的文字一秒钟转化为各种炫酷的视觉效果,比如图表.流程图.信息图啥的.如 ...

  9. 使用vscode开发微信小程序

    1. 安装插件 2. 文件-打开文件夹-将新建的微信小程序导入,代码会有高亮的效果 3. 编辑内容,查看效果,如果有就说明插件引入成功.

  10. Spark core 总结

    Spark RDD五大特性 1.RDD由一组partition组成 2.每一个分区由一个task来处理 3.RDD之间有一些列依赖关系 4.分区类算子必须作用在kv格式得RDD上 5.spark为ta ...