AOP——面向切面编程
软件有一个重要的概念:关注点分离:不同的问题交给不同的部分去解决。
AOP是一种关注点分离的技术,写Web时需要写缓存、业务逻辑、日志、出错处理等等东西都要放在一起,为了将业务各个功能分离开切面就出现了,当业务功能代码和切面代码分开之后架构就会变得高内聚低耦合。
如果模块化之后虽然模块本身的成本降低了,但是接口的开发的成本又升高了我们为了保证业务的完整性就需要使用切面将业务去进行合并。
AOP——三种置入方式:
- 编译的时候置入:需要特殊的Java编译器,如AspectJ
- 类加载的时候置入:需要特殊的Java编译器,如AspectJ和AspectWerkz
- 运行的时候置入:Spring常规的时候采用的方式,基于动态代理,实现简单。
下面的简单的demo
- 首先用@Aspect创建一个切面,然后用@Component加入进切面
- 分别使用@PointCut,@Before,@AfterReturning定义针对切面要做的事情与配置
接下来介绍几个AOP相关的主要名词概念:
- Aspect:通用功能的代码实现
- Target:被织入Aspect的对象
- Join Point:可以作为切入点的机会,所有方法都可以作为切入点
- PointCut:Aspect实际被应用在的Join Point,支持正则表达式
- Advice:类里的方法以及这个方法如何织入到目标方法的方式
- Weaving:AOP的实现过程
AOP的实现:JdkProxy与Cglib
具体使用哪种方式由AopProxyFactory根据AdvisedSupport对象的配置去决定。
默认的策略是如果目标类是接口就使用JDKProxy去实现,否则用Cglib。
如果不是接口默认是用Cglib,底层原理是ASM字节码框架用继承的方法动态生成目标类的代理。
从性能角度来看,ASM生成类之后的执行过程中比较高效,而反射机制在生成类过程中比较高效。
Spring中真实实现类的逻辑包含在getBean中,getBean方法返回的实际上使Proxy的实例,而Proxy实例是Spring采用的JDKProxy或者Cglib动态生成的。