1、什么是AOP?AOP的各个构成部分的概念?
AOP是面向切面的编程思想:将业务逻辑模块中,需要进性处理的功能点,从逻辑上的角度将其作为一个整体进性管理;这个整体,就可以看做是有这些不同模块中的逻辑点构成的一个面;这个面就是切面;
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
连接点(Joinpoint):进性切面业务处理时的时机点,例如方法执行前、方法执行后、抛出异常等时机点;
增强(Advice):添加特定连接点上的一段业务逻辑处理代码;也就是在连接点上执行的业务处理过程;
就是在特定连接点上触发的一组动作;
切入点(PointCut):被增强的连接点就是切入点; 添加了增强功能的连接点;
织入(Weaving):将增强添加到目标对象的具体的连接点的过程。也就是将增强和连接点结合的过程就是织入;
切面(Aspect):切面由切入点和增强构成。切面就是切入点的集合;AOP就是通过切面来管理连接点和增强的;
目标对象(Target):需要添加增强的目标类。(被代理的目标类)
代理(Proxy):目标对象通过AOP生成的代理对象;代理和目标对象之间是代理和被代理的关系;
引入(Introduction):是一种特殊的增强;可以为目标对象添加一些属性和方法;一般用作动态的给目标对象附加一些行为能力;
总结:
把"增强"使用"织入"方式结合在"连接点"上构成了"切入点",“切入点"汇集成"切面” ;
AOP就是使用动态代理等方式对切面的管理机制;
2、AOP的实现方式?【拦截器思想、动态代理】
AOP的拦截功能是由java中的动态代理来实现的。说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执行。不同的切入时机对应不同的Interceptor的种类,如BeforeAdviseInterceptor,AfterAdviseInterceptor以及ThrowsAdviseInterceptor等)。
那么动态代理是如何实现将切面逻辑(advise)织入到目标类方法中去的呢?下面我们就来详细介绍并实现AOP中用到的两种动态代理。
AOP的源码中用到了两种动态代理来实现拦截切入功能:jdk动态代理和cglib动态代理。两种方法同时存在,各有优劣。jdk动态代理是由java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。
3、Spring容器初始化的流程?
Resource定位;指对BeanDefinition的资源定位过程。Bean 可能定义在XML中,或者是一个注解,或者是其他形式。这些都被用Resource来定位, 读取Resource获取BeanDefinition 并注册到 Bean定义注册表中。
BeanDefinition的载入;把用户定义好的Javabean表示为IoC容器内部的数据结构,这个容器内部的数据结构就是BeanDefinition。
向IoC容器注册这些BeanDefinition。
获取Bean的流程
4、Spring bean的加载过程?以及生命周期?
/**
* bean声明周期:
* bean创建 -- 初始化 -- 销毁过程
* 容器管理bean的生命周期
* 我们可以自定义初始化和销毁方法,容器在bean进行到当前声明周期的时候拉力调用我们自定义的初始化和销毁方法
*
* 构造(对象创建):
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
* 初始化:
* 对象创建完成,并赋值好,调用初始化方法
* 销毁:
* 单实例:在容器关闭的时候进行销毁
* 多实例:容器不会管理这个bean,所以容器不会调用销毁方法
*
*
*
* 1)指定初始化和销毁方法 -- car
* 在beans文件中指定init-method 和 destroy-method方法
* 通过@Bean指定initMethod和destroyMethod
*
* 2)通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁容器)--cat
* 3)可以使用JSR250: --dog
* @PostConstruct:在bean创建完成并且属性赋值完成,来执行初始化
* @PreDestroy:在容器销毁之前通知我们进行清理工作
* 4)BeanPostProcessor[interface]:bean的后置处理器 -- MyBeanPostProcessor
* 在bean初始化前后进行一些处理工作
* postProcessBeforeInitialization:在初始化之前工作
* PostProcessAfterInitialization:在初始化之后工作
* 遍历得到容器中所有的BeanPostProcessor,挨个执行beforeInitialization,一旦返回null,
* 就跳出for循环,不会执行后面的BeanPostProcessor。
*
*
* */