Spring学习笔记|第二篇:Spring-AOP

1.AOP概念

在开发过程中会产生一些与主业务逻辑关系不大,但散落在代码各个部分难以维护的横切性问题,如日志记录、权限验证、事务管理、异常处理等。AOP就是处理这些横切性问题,AOP思想就是将这些问题与主业务分开,从而达到与主业务解耦的目的。

2.AOP术语

(1) Join point: 连接点,目标对象中的方法

(2) Advice: 通知,特定连接点上具体操作,具体有"around"、"before"和"after"三种通知

(3) Pointcut: 切点,多个连接点的集合,可用表达式表示目标连接点集合

(4) Target object: 目标对象,即需要增加的对象

(5) Aop proxy: 代理对象,Aop底层为jdk动态代理和cgLib代理,aop实质即为目标对象生成代理对象,从而对目标对象进行增强

(6) Weaving: 织入,将需要增强的通知增强进目标对象中

3. @AspectJ 支持

Spring对Aop的支持,底层自己实现了一套AOP逻辑,只是引入了AspectJ的注解支持,AOP是一种概念,SpringAop、AspectJ均为Aop的实现,Spring实现的Aop逻辑复杂,故引入了AspectJ的注解,底层仍为自己实现

3.1 Spring中引入切面实现

(1) 引入AspectJ依赖,目的为提供AspectJ注解支持

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

(2) 配置文件中增加@EnableAspectJAutoProxy

@Configuration
@ComponentScan("com.study.spring")
@EnableAspectJAutoProxy
public class SpringConfig {

}

(3) 书写切面对象,并将该对象交由Spring管理

@Aspect
@Component
public class UserAop {

}

(4)书写切入点

@Pointcut("execution(* com.study.spring.dao.*(..))")
public void pointCut(){

}

(5)书写通知即可完成切面实现

@Before("pointCut()")
public void beforeAdvice(){
    System.out.println("before advice");
}

3.2 pointcut切面表达式

  • execution

表示匹配连接点对应的包及其子包对象及对象中的方法,最小作用单元为方法级别

execution(* * com.study.spring.dao.*.*(..))

表示式解析:

第一个*:表示方法访问级别,可以为public,private,protect,下述表达式表示只会给访问级别为public的方法进行增aop

execution(public * com.study.spring.dao.*.*(..))

第二个*:表示方法返回类型,下述表达式表示只会给没有返回值的方法进行aop

execution(void com.study.spring.dao.*.*(..))

第三个表示式:表示方法路径,下述表示dao包及其所有子包,对应所有方法均为被增强

execution(* com.study.spring.dao..*(..))

execution表达式为我们常用表达式,表达式也比较多,在此就不做过多介绍,实际开发中可根据实际需求进行配置

  • within

表示匹配连接点对应的包及其子包对象,最小作用单元为对象级别

(1)表示dao包下所有对象均会被增强

within(void com.study.spring.dao.*)

(2)下述表达式表示dao包及其子包中所有对象均会被增强

within(void com.study.spring.dao..*)
  • target 及this

target:表示目标对象,即aop对应的原始对象
this:表示代理对象

/**
 * 此处需要注意的是,如果配置设置proxyTargetClass=false,或默认为false,则是用JDK代理,否则使用的是CGLIB代理
 * JDK代理的实现方式是基于接口实现,代理类继承Proxy,实现接口。
 * 而CGLIB继承被代理的类来实现。
 * 所以使用target会保证目标不变,关联对象不会受到这个设置的影响。
 * 但是使用this对象时,会根据该选项的设置,判断是否能找到对象。
 */
@Pointcut("target(com.study.dao.IndexDaoImpl)")//目标对象,也就是被代理的对象。限制目标对象为com.study.dao.IndexDaoImpl类
@Pointcut("this(com.study.dao.IndexDaoImpl)")//当前对象,也就是代理对象,代理对象时通过代理目标对象的方式获取新的对象,与原值并非一个
@Pointcut("@target(com.study.anno.ExtAnno)")//具有@ExtAnno的目标对象中的任意方法
@Pointcut("@within(com.study.anno.ExtAnno)")//等同于@target
  • @target、@arges、@within、@annotation

带有@,与上述表示方式类似,唯一区别在于这些表达式只针对于注解形式

切点配置的表达式较大,可根据实际开发中所遇具体配置,在此不做过多介绍

3.3 Advice通知

(1)前置通知(@before):表示在方法执行前进行增强

@Before("pointCut()")
public void beforeAdvice(){
    System.out.println("before advice");
}

(2)后置通知(@After):表示在方法执行后进行增强

 @After("pointCut()")
  public void beforeAdvice(){
    System.out.println("after advice");
  }

(3)环绕通知(@Around):表示在方法执行前、执行后均增强

@Around("pointCut()")
public void aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("before around advice");
    pjp.proceed();
    System.out.println("after around advice");
}

pjp.proceed()方法表示目标对象中要增加的方法,即为连接点方法

pjp常用方法:

getArgs():返回方法参数

getThis():返回代理对象

getTarget():返回目标对像`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值