AOP 面向切面编程
代理行为
静态代理
静态代理三要素:
1. 接口(共同需求,行为)
2. 目标类 (需求类)
3. 代理类 : 持有目标类引用 增强目标类行为
静态代理特点:
- 运行前需要先生成代理类
- 代理目标类的类型固定(只能执行一件事的代理)
缺陷: 对于每个接口都需要提供一个代理类,需要事先生成大量代理类,不利于维护
动态代理
JDK:目标类必须存在接口实现 否则无法生成动态代理
代理类与目标类不能互相转换
制作代理类效率高
CGLIB: 对于目标类是否存在接口实现没有要求(通过继承思想实现)
代理类属于目标类的子类
目标类存在接口实现 效率没JDK高
aop 模式
概念:aop是通过代理的方式,对于某些重复的功能的用代理的方式解决,提高了代码的复用性,降低了耦合度
aop环境:
<!--
需要导入相应的外部 依赖 与对应的xml配置
-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!--
xml 配置 在 通过<aop:aspectj-autoproxy></aop:aspectj-autoproxy> 开启aop
-->
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
实现方式:
注解:
<!--
通过注解的方式声明切面,连接点,通知
@Pointcut("execution(* com.shsxt.user..*.*(..))")
(两个点带包当前包与他的所有子包,一个代表当前包)
execution(方法类型 包..所有类。所有方法(..))
-->
1. @Aspect (声明切入面)
2. @Pointcut("execution(* com.shsxt.user..*.*(..))") (设置切入点)
3. @Before(value = "cut()") (目标类方法运行前通知)
4. @AfterReturning(value = "cut()")(目标类方法正常结束通知 运行出错不运行此注释的方法)
5.@AfterThrowing(目标类方法运行出错通知)
6.@After()(目标类方法运行后通知 不在乎是否正常运行)
7.@Around()(环绕式运行)
xml配置:
<!-- aop 相关配置 -->
<aop:config>
<!-- aop 切面配置 -->
<aop:aspect ref="logCut">
<!-- 定义 aop 切入点 -->
<aop:pointcut expression="execution (* com.shsxt.service..*.*(..))"
id="cut"/>
<!-- 配置前置通知 指定前置通知方法名 并引用切入点定义 -->
<aop:before method="before" pointcut-ref="cut"/>
<!-- 配置返回通知 指定返回通知方法名 并引用切入点定义 -->
<aop:after-returning method="afterReturning" pointcut-ref="cut"/>
<!-- 配置异常通知 指定异常通知方法名 并引用切入点定义 -->
<aop:after-throwing method="afterThrowing" throwing="e" pointcutref="cut"/>
<!-- 配置最终通知 指定最终通知方法名 并引用切入点定义 -->
<aop:after method="after" pointcut-ref="cut"/>
<!-- 配置环绕通知 指定环绕通知方法名 并引用切入点定义 -->
<aop:around method="around" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>