六、spring原理(3)AOP原理

一、概念

"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块, 并将其命名为"Aspect",即切面。

所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。 

使用"横切"技术,AOP 把软件系统分为两个部分:核心关注点和横切关注点。

业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

AOP主要应用场景有: 

  1. Authentication 权限
  2. Caching 缓存
  3. Context passing 内容传递
  4. Error handling 错误处理
  5. Lazy loading 懒加载
  6. Debugging  调试
  7. logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  8. Performance optimization 性能优化
  9. Persistence  持久化
  10. Resource pooling 资源池
  11. Synchronization 同步
  12. Transactions 事务 
     

二、AOP核心

 

1.切面(aspect):

类是对物体特征的抽象,切面就是对横切关注点的抽象 

2.横切关注点:

对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点。 

3.连接点(joinpoint):

被拦截到的点,因为 Spring 只支持方法类型的连接点,所以在 Spring 中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。 

4.切入点(pointcut):

对连接点进行拦截的定义 

5.通知(advice):

所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、 异常、最终、环绕通知五类。

6.目标对象:

代理的目标对象 

7.织入(weave):

将切面应用到目标对象并导致代理对象创建的过程 

8.引入(introduction):

在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

三、AOP 两种代理方式 

Spring 提供了两种方式来生成代理对象: JDKProxy 和 Cglib,具体使用哪种方式生成由 AopProxyFactory 根据 AdvisedSupport 对象的配置来决定。默认的策略是如果目标类是接口, 则使用JDK动态代理技术,否则使用Cglib来生成代理。 

1.JDK 动态接口代理

JDK 动态代理主要涉及到 java.lang.reflect 包中的两个类:Proxy 和 InvocationHandler。

InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类 的代码,动态将横切逻辑和业务逻辑编制在一起。

Proxy 利用 InvocationHandler 动态创建 一个符合某一接口的实例,生成目标类的代理对象。 

2.CGLib 动态代理

CGLib全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库, 可以在运行期扩展 Java 类与实现 Java 接口,CGLib 封装了 asm,可以再运行期动态生成新 的 class。

和 JDK 动态代理相比较:JDK 创建代理有一个限制,就是只能为接口创建代理实例, 而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理。 

四、示例代码

@Aspect 
public class TransactionDemo { 
  @Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))") 
  public void point(){     
  }   
  @Before(value="point()") 
  public void before(){ 
    System.out.println("transaction begin"); 
  } 
  @AfterReturning(value = "point()") 
  public void after(){ 
    System.out.println("transaction commit"); 
  }
  @Around("point()") 
  public void around(ProceedingJoinPoint joinPoint) throws Throwable{ 
    System.out.println("transaction begin"); 
    joinPoint.proceed(); 
    System.out.println("transaction commit"); 
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值