spring03_03_[掌握]Spring中AOP使用(含源码下载)基于XML、注解的AOP配置
先上代码:项目源码下载(软件:IDEA):
基于XML的AOP配置
链接:https://pan.baidu.com/s/1wSbq5jYeykOxTUmjEvmz5A
提取码:9sox
基于注解的AOP配置
链接:https://pan.baidu.com/s/17QO6XzA5UGPHcW8JBrcHeg
提取码:tw1g
AOP相关术语
- Joinpoint(连接点)
横切程序执行的特定位置,比如类开始初始化前,类初始化之后,类中某个方法调用前、调用后,方法抛出异常后等,这些代码中的特定点就称为“连接点”。
Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。
我们知道黑客攻击系统需要找到突破口,没有突破口就无法进行攻击,从这一角度上来说,AOP是一个黑客(因为它要向目前类中嵌入额外的代码逻辑),连接点就是AOP向目标类打入楔子的候选点。
2.Pointcut(切入点)
一个类中可以有很多个方法,每个方法又有多个Joinpoint,在这么多个方法中,如何定位到自己感兴趣的方法呢?靠的是切点
注意:切点只定位到某个方法上,所以如果希望定位到具体连接点上,还需要提供方位信息
比如:如果把一个方法理解成数据表中的一条记录的话,那么切入点就好比你select语句的where条件 ,就可以定位到你感兴趣的方法
3.Advice(通知/增强)
增强的第一层意思就是你的横切逻辑代码(增强逻辑代码)
在Spring中,增强除了用于描述横切逻辑外,包含一层意思就是横切逻辑执行的方位信息。刚刚说了切点只能定位到方法,在进一步使用方位信息就可以定位到我们感兴趣的连接点了(方法调用前、方法调用后还是方法抛出异常时等)。
4.Target(目标对象)
增强逻辑的织入目标类。比如未添加任何事务控制的AccountServiceImplNoTcf类
5.Weaving(织入)
织入是将增强逻辑/横切逻辑添加到目标类具体连接点上的过程,AOP像一台织布机,将目标类、增强或者引介通过AOP(其实就是动态代理技术)这台织布机天衣无缝地编织到一起。
Spring采用动态代理织入。
6.Proxy(代理)
一个类被AOP织入增强后,就产出了一个结果类,它是融合了原类和增强逻辑的代理类。
7.Aspect(切面)
切面由切点和增强(引介)组成。
切面=切点+增强
=切点+方位信息+横切逻辑
=连接点+横切逻辑
最终切面完成:把横切逻辑织入到哪些方法的方法前/后等
本质:把横切逻辑增强到连接点(切点和方位信息都是为了确定连接点)上
Spring关于JDK/CGLIB动态代理的选择
Spring发现涉及到接口那就使用JDK动态代理,如果不涉及接口就使用CGLIB动态代理
AOP:日志、性能监控、事务、权限控制
基于XML的AOP配置
需求:在Service层代码的不同方法的不同连接点JoinPoint织入日志
把Account表的service层进行crud模拟(dao层就不需要了)
引入POM坐标
[code]<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency>
applicationContext.xml配置
<aop:config> 所有aop配置的根标签
<aop:aspect id="logAspect" ref="log"> 配置切面对象,id自定义,ref横切逻辑类的bean标签id值
<aop:pointcut> 配置切入点
属性值:id自定义
属性值:expression 匹配方法的表达式
<aop:before> 被切入的方法前执行
属性method:printBeforeMethod切入的方法名
属性pointcut-ref:切入点标签的id属性值
[code]<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <context:component-scan base-package="com.itheima"></context:component-scan> <!-- 横切逻辑配置--> <bean id="log" class="com.itheima.utils.LogUtil"> </bean> <!-- 配置aop的根标签--> <aop:config> <!-- 切面配置--> <aop:aspect id="logAspect" ref="log"> <!-- 配置切入点 before:方法执行之前 method:切入的方法名 pointcut:感兴趣的方法,被切入的方法 --> <!--<aop:before method="printBeforeMethod" pointcut="execution( int com.itheima.service.AccountService.saveAccount(com.itheima.pojo.Account))"></aop:before>--> <!-- 表达式配置 方法参数:* 匹配任意参数,必须有参数 .. 匹配任意参数,有无参数均可 方法名:* 返回值:* --> <aop:pointcut id="point1" expression="execution( * com.itheima.service.AccountService.*(..))"></aop:pointcut> <aop:before method="printBeforeMethod" pointcut-ref="point1"></aop:before> <aop:after-returning method="pringAfterReturn" pointcut-ref="point1"></aop:after-returning> <aop:after-throwing method="printAfterThrowing" pointcut-ref="point1"></aop:after-throwing> <aop:after method="printAfterMethod" pointcut-ref="point1"></aop:after> </aop:aspect> </aop:config> </beans>
日志对象:横切逻辑
[code]public class LogUtil { //方法执行之前 public void printBeforeMethod(){ System.out.println("方法之前执行"); } //方法执行之后打印 public void printAfterMethod(){ System.out.println("方法执行之后"); } //方法异常执行打印 public void printAfterThrowing(){ System.out.println("方法异常时"); } //方法正常执行打印 public void pringAfterReturn(){ System.out.println("方法正常时"); } }
service层
[code]@Service("accountServiceImpl") public class AccountServiceImpl implements AccountService { public int saveAccount(Account account) { System.out.println("模拟保存账户"); return 0; } @Override public int updateAccountById(Account account) { System.out.println("模拟更新账户"); return 0; } @Override public int deleteAccountById(int id) { System.out.println("模拟删除账户"); return 0; } @Override public Account queryAccountById(int id) { System.out.println("模拟查询账户"); return null; } }
测试类
[code]@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class MainTest { @Autowired @Qualifier("accountServiceImpl") private AccountService accountService; @Test public void testAop(){ accountService.saveAccount(new Account()); // accountService.queryAccountById(1); } }
环绕通知
它是spring为我们提供的一种可以在代码中手动控制增强方法何时执行的方式,灵活度比较高,设置可以控制原业务逻辑是否执行。
注意:通常情况下,环绕通知都是独立使用的,不要和上面的四种通知类型混合使用
<aop:around method="printRound" pointcut-ref="point1"></aop:around> 环绕通知配置
ProceedingJoinPoint进程切入点对象,执行我们的业务逻辑方法
方法:proceed() 执行我们自己的业务逻辑方法
applicationContext.xml配置
[code]<aop:around method="printRound" pointcut-ref="point1"></aop:around>
日志对象:横切逻辑
[code]//环绕通知 public Object printRound(ProceedingJoinPoint proceedingJoinPoint){ Object result = null; try{ System.out.println("方法前执行"); result = proceedingJoinPoint.proceed(); System.out.println("方法正常执行"); }catch (Throwable ex){ ex.printStackTrace(); System.out.println("方法异常执行"); } System.out.println("方法后执行"); return result; }
基于注解的AOP配置
创建框架启动配置类
[code]@Component @ComponentScan("com.itheima") //启用动态代理 @EnableAspectJAutoProxy public class SpringConfig { }
测试类
[code]@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class MainTest { @Autowired @Qualifier("accountServiceImpl") private AccountService accountService; @Test public void testAop(){ accountService.saveAccount( new Account()); } }
学习spring中的AOP时要明确的事
- AOP的使用场景
AOP的应用场景往往是受限的,它一般只适合于那些具有横切逻辑的应用场合:如性能监测、访问控制、事务管理以及日志记录等。不过,这丝毫不影响AOP作为一种新的软件开发思想在软件开发领域所占有的地位。
2.开发阶段(我们完成)
编写核心业务代码
大部分程序员来做,要求熟悉业务需求。
抽取公用代码制作成通知,进行AOP配置
一般由专门的AOP编程人员来做
3.运行阶段(Sprin 1c140 g框架完成)
Spring框架监控切入点方法的执行。一旦监控到切入点方法被运行,Spring框架使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。
- spring aop的使用(注解方式以及基于xml配置方式)
- spring aop的使用(注解方式以及基于xml配置方式)
- spring aop的使用(注解方式以及基于xml配置方式)
- 8 -- 深入使用Spring -- 4...6 AOP代理:基于注解的XML配置文件的管理方式
- 基于注解的Spring AOP的配置和使用--转载
- 基于注解的Spring AOP的配置和使用--转载
- 【Spring】基于注解的Spring AOP的配置和使用
- 基于注解的Spring AOP的配置和使用--转载
- Spring中基于配置XML与Annotation注解配置AOP
- 基于注解的Spring AOP的配置和使用
- 基于注解的Spring AOP的配置和使用
- spring-06 之AOP 面向切面编程二 基于注解和基于xml配置文件的aop操作
- 基于注解的Spring AOP的配置和使用--转载
- 基于注解的Spring AOP的配置和使用--转载
- 基于注解的Spring AOP的配置和使用
- Spring基础入门五:基于XML和注解的Spring的AOP使用
- 基于注解的Spring AOP的配置和使用
- 基于注解的Spring AOP的配置和使用--转载
- 基于注解的Spring AOP的配置和使用--转载
- Unit03: Spring Web MVC简介 、 基于XML配置的MVC应用 、 基于注解配置的MVC应用