目录
第一种,有接口情况,使用JDK动态代理(创建接口实现类代理对象,增强类的方法)
第二种,没有接口情况,使用CGLIB动态代理(使用子类的动态代理对象,增强类的方法)
实现了接口,则会采用jdk动态代理,没有则会才用cglib动态代理
什么是AOP?
AOP的作用和优势
AOP的底层实现
1、AOP底层使用动态代理
第一种,有接口情况,使用JDK动态代理(创建接口实现类代理对象,增强类的方法)
代理对象和目标对象,有种相当兄弟的关系
第二种,没有接口情况,使用CGLIB动态代理(使用子类的动态代理对象,增强类的方法)
代理对象和目标对象,有种相当父子的关系(不是基于继承,而是通过动态代理实现)
AOP相关概念
AOP的开发明确的事项
实现了接口,则会采用jdk动态代理,没有则会才用cglib动态代理
知识要点
开发流程
第一步:导入AOP坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!-- AOP模块-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
第二步:创建目标接口和目标类(才有jdk动态代理)
目标接口:
public interface TargetInterface {
public void save();
public void save1();
}
目标方法:
public class Target implements TargetInterface {
@Override
public void save() {
System.out.println("running------");
}
public void save1() {
System.out.println("running1------");
int a =1/0;
System.out.println("running2------");
}
}
第三步:创建切面类(内部放增强方法)
public class MyAspect {
// 增强--前置
public void before(){
System.out.println("前置增强----------");
}
// 增强--后置
public void after(){
System.out.println("后置增强----------");
}
// 增强--环绕
//ProceedingJoinPoint===切点
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("环绕前增强----------");
//切点方法
Object proceed = point.proceed();
System.out.println("环绕后增强----------");
return proceed;
}
// 增强--异常
public void throws11(){
System.out.println("异常增强----------");
}
// 增强--最终
public void final11(){
System.out.println("最终增强----------");
}
}
第四步:将目标类和切面类交给Spring容器管理
<!--目标对象-->
<bean id="target" class="com.example.aop.Target"></bean>
<!--切面对象-->
<bean id="myAspect" class="com.example.aop.MyAspect"></bean>
第五步:将增强方法织入目标类的方法(切点)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--目标对象-->
<bean id="target" class="com.example.aop.Target"></bean>
<!--切面对象-->
<bean id="myAspect" class="com.example.aop.MyAspect"></bean>
<!-- (先声明aop) 配置织入,告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置……)-->
<aop:config>
<!--声明切面-->
<aop:aspect ref="myAspect">
<!--切面 == 切点+增强 把增强类中的before方法织入目标对象的save方法(切点)上 -->
<aop:before method="before" pointcut="execution(public void com.example.aop.Target.save())" /><!--切点表达式-->
</aop:aspect>
</aop:config>
</beans>
xml配置AOP详解
1--切点表达式的写法
下面例如,第三个例子最常用
2--通知的类型
总共有5种通知。
3--切点表达式的抽取
<!-- (先声明aop) 配置织入,告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置……)-->
<aop:config>
<!--声明切面-->
<aop:aspect ref="myAspect">
<!--切面 == 切点+增强 把增强类中的before方法织入目标对象的save方法(切点)上 -->
<!--抽取切点表达式 -->
<aop:pointcut id="myPointcut" expression="execution(* com.example.aop.*.*(..))"></aop:pointcut>
<!--使用抽取的切点表达式-->
<aop:around method="around" pointcut-ref="myPointcut"/>
<aop:before method="before" pointcut-ref="myPointcut"/>
<!-- <aop:before method="before" pointcut="execution(public void com.example.aop.Target.save())" /><!–切点表达式–>-->
<!-- 前置通知<aop:before method="before" pointcut="execution( * com.example.aop.*.*(..))" />切点表达式-->
<!-- <!–环绕通知–><aop:around method="around" pointcut="execution(* com.example.aop.*.*(..))"/>-->
<!-- <!–异常通知–><aop:after-throwing method="throws11" pointcut="execution(* com.example.aop.*.save1(..))"/>-->
<!-- <!–最终通知–><aop:after method="final11" pointcut="execution(* com.example.aop.*.save(..))"/>-->
</aop:aspect>
</aop:config>