代理模式和AOP
静态代理模式
-
缺点:一个真实角色就会产生一个代理角色,类多了代码量大
-
在不改变原来的代码的情况下,实现了对原有功能的增强,是AOP中最核心的思想
-
AOP:纵向开发,横向开发(面向切面编程)
动态代理模式(基于反射)
-
一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口
-
动态代理分为两大类:基于接口--JDK动态代理 基于类--cglib
-
InvocationHandler接口:调用处理程序,实现动态代理的类
-
Proxy类:提供创建动态代理类和实例的静态方法
AOP
相关名词
-
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
-
切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
-
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
-
目标(Target):被通知对象。
-
代理(Proxy):向目标对象应用通知之后创建的对象。
-
切入点(PointCut):切面通知 执行的 “地点”的定义。
-
连接点(JointPoint):与切入点匹配的执行点。
通过 Spring API 实现
-
使用AOP织入,需要导入一个依赖包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency> -
写业务接口和实现类
-
写增强类 , 一个前置增强一个后置增强
-
最后去spring的文件中注册 , 并实现aop切入实现 , 注意导入约束
<!--aop的配置-->
<aop:config>
<!--切入点 expression:表达式匹配要执行的方法-->
<aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<!--执行环绕; advice-ref执行方法 . pointcut-ref切入点-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
自定义类实现
-
写一个切入类
-
去spring中配置
<!--第二种方式自定义实现-->
<!--注册bean-->
<bean id="diy" class="com.kuang.config.DiyPointcut"/>
<!--aop的配置-->
<aop:config>
<!--第二种方式:使用AOP的标签实现-->
<aop:aspect ref="diy">
<aop:pointcut id="diyPonitcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<aop:before pointcut-ref="diyPonitcut" method="before"/>
<aop:after pointcut-ref="diyPonitcut" method="after"/>
</aop:aspect>
</aop:config>
使用注解实现
-
编写一个注解实现的增强类
-
在Spring配置文件中,注册bean,并增加支持注解的配置
<bean id="annotationPointcut" class="com.kuang.config.AnnotationPointcut"/>
<aop:aspectj-autoproxy/>