Spring基础

AOP 面向切面编程

通知、连接点、切点、切面

Spring提供 4 种类型的AOP支持:

  • 基于代理的经典SpringAOP:使用ProxyFactoryBean。
  • 纯POJO切面:使用XML配置;
  • @ASpectJ注解驱动的切面;
  • 注入式AspectJ切面。

前三种都属于SpringAOP,基于代理(JDK动态代理和Cglib)。第四种属于AspectJ。

通过切点来选择连接点

切点表达式:

execution(* a.b.c.method(...)) && bean('some')

execution(* soundSystem.CompactDisc.playTrack(int)) && args(trackNumber)

1. 使用注解创建切面

@Aspect 注解 表明类是一个切面

Spring使用了 AspectJ库的注解并且使用 AspectJ库对切点表达式进行解析和匹配(需要aspectjweaver.jar),但AOP运行时并不使用 AspectJ的编译器和织入,仍然是使用纯粹的SpringAOP实现。

  1. 切面的方法前使用注解:

    @Before("切点表达式") 通知方法会在目标方法调用之前执行;

    @After("切点表达式") 通知方法会在目标方法返回或抛出异常后调用;

    @AfterReturning("切点表达式") 通知方法会在目标方法返回后调用;

    @AfterThrowing("切点表达式") 通知方法会在目标方法抛出异常后调用;

    @Around("切点表达式") 通知方法会将目标方法封装起来。
  2. @Pointcut("切点表达式") 注解方法,定义一个切点

该切面类需要装配为Spring中的bean,并且需要在配置类前使用@EnableAspectJAutoProxy 注解启用自动代理。

环绕通知:

@Aspect
public class Audience{ @Pointcut("execution(** concert.Performance.perform(..))")
public void performance(){} @Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp){
try{
//Before前置通知
jp.proceed(); //调用被通知的方法,可以不调用以阻塞,也可以多次调用
//AfterReturning后置通知
}catch(Throwable e){
//AfterThrowing后置通知
}
}
}

通过注解引入新功能:

@Aspect
public class EncoreableIntroducer{ //定义切面
@DeclareParents(valule = "concert.Performance+", //哪种类型的bean要引入该接口
deafultImpl = DefaultEncoreable.class) //为引入接口提供实现的类
public static Encoreable encoreable; //要引入的接口
}

上述类需要被声明为一个bean

2. 在XML中声明切面

如果你需要声明切面,但是又不能为通知类切面类添加注解的时候(没有源码),那么就必须转向XML配置了

  • [ ] TODO

3. 注入AspectJ切面

首先配置AspectJ的环境:

  1. 在https://www.eclipse.org/aspectj/downloads.php#ides 下载aspectj-1.x.x.jar;
  2. 使用java -jar aspectj-1.1.0.jar进行安装;
  3. 将 ${aspect_path}/lib/aspectjrt.jar加入项目的依赖;

    在IDE中将编译器设置为Ajc,路径为${aspect_path}/bin/aspectjtools.jar;
文件 CriticAspect.aj:

package concert;

public aspect CriticAspect {    //定义切面,需在XML中配置为bean

    pointcut performance():execution(* concert.Performance.perform(..));    //定义切点

    after():performance(){  //定义通知
System.out.println(criticismEngine.getCriticism());
} private CriticismEngine criticismEngine; //将被注入bean
// 通过属性的setter()函数实现注入
public void setCriticismEngine(CriticismEngine criticismEngine) {
this.criticismEngine = criticismEngine;
}
}

最新文章

  1. jdk顺序表笔记
  2. 【java开发系列】—— JDK安装
  3. 源码生成deb包
  4. codevs1024一塔湖图(丧心病狂的建图)
  5. Open Replicator
  6. MYSQLI - mysqli
  7. 好题 线段树对数据的保存+离线的逆向插入 POJ 2887
  8. Django导入外部js、css、图片等巨大的坑
  9. SharePoint Patterns and Practices 简介
  10. [Jenkins Git] 在Jenkins上拉代码总是失败,跑去本地看,提示输入用户名和密码,但是Jenkins上已经配置了正确的用户名和密码
  11. Linux安装Apache常见报错(一)
  12. AFN 请求报 415错误解决方案
  13. Java如何获取图片验证码保存
  14. python网页爬虫开发之五-反爬
  15. 51单片机的idata,xdata,pdata,data的详解(转)
  16. Druid在有赞的实践
  17. 获取bean的两种方式
  18. 新转移注意(caffe):ImportError: libcudart.so.7.0: cannot open shared object file: No such file or directory
  19. 遇到了IE10不能登录的问题,很早就有解决方案了
  20. Linux远程管理器xshell和xftp使用教程,以及遇到关闭Xshell后项目也停止的解决方法

热门文章

  1. Netty 面试题 (史上最全、持续更新)
  2. 6.10考试总结(NOIP模拟6)
  3. 消失之物(背包DP)(容斥或分治)
  4. python 字典和列表嵌套用法
  5. 10.8、mysql日志
  6. uniapp uni.navigateTo 传值传对象
  7. 通过winsw将jar包做成window后台服务运行
  8. html的题库(含答案)
  9. CRM系统如何帮助企业管理多条业务线的?
  10. 安卓手机改造服务器——解决chroot下无法使用systemctl