#AOP 个人理解
1.面向切面编程:1.相较与OOP 面向对象编程 。面向对象编程的结构是一个从上到下 金字塔形的结构。向上抽取共性的内容。
而AOP是通过从左往右的给金字塔每一层进行统一的添加,或部分的添加新功能。
2.简单说做到的事就是。在不改变原来结构内容的情况下。低耦合的控制执行的内容。通过外部的方式改变
方法的执行内容,如果不需要增强功能,断掉该功能不影响原有的功能。
优点 : 1.低耦合 2.共性的添加某功能 ,高效率 3.便于维护
2.底层技术支持:
1.jdk 动态代理
Proxy.newProxyInstence():
1. 获取动态代理对象的原理:在运行期动态的生成对象,生成的对象实现目标对象的所有接口,重写所有方法,对调用的方法,
进行增强。这种代理方式是实现共同的接口,所以,目标对象必须有接口。
2.底层代码:
/*java
Target target = new Target(); //创建目标对象
//创建代理对象
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass()
.getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("前置增强代码...");
Object invoke = method.invoke(target, args);
System.out.println("后置增强代码...");
return invoke;
}
}
);
*/
2.cglib 动态代理:
Enhancer enhancer = new Enhancer();
1.获取动态代理对象的原理:在运行期间动态的生成对象,生成的对象继承目标对象,重写目标对象的所有方法,对调用的
方法进行增强,这种代理方式是继承目标对象,一般使用于无接口的对象。
2.底层代码:
/* java
Target target = new Target(); //创建目标对象
Enhancer enhancer = new Enhancer(); //创建增强器
enhancer.setSuperclass(Target.class); //设置父类
enhancer.setCallback(new MethodInterceptor() { //设置回调
@Override
public Object intercept(Object o, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
System.out.println("前置代码增强....");
Object invoke = method.invoke(target, objects);
System.out.println("后置代码增强....");
return invoke;
}
});
Target proxy = (Target) enhancer.create(); //创建代理对象
*/
#Spring-AOP
1.相关名称解释
1.Target:目标对象 需要被增强功能的对象,一般是多个。通过切面表达式统一指代。
2.Proxy:代理类 一个目标对象被织入增强,所产生的代理类。
3.JoninPoint 连接点 所有的类中的方法都可以是连接点。
4.Pointcut 切点 被选中的需要增强的方法,一般在切面表达式范围内的。
5.Advice 通知/增强方式 对目标方法增强的方式,前,后,最后,环绕,错误 + 增加进去的功能。
6.Aspect 切面 需要对目标方法 ①增加的方法 和 ②增强的方式 和 ③被增强目标方法 的结合 切点+通知
7.Weaving 织入 把 切面(切点+通知)和 连接点 结合在一起的过程
核心在4.5.6
2.配置的三个明确
1.明确什么方式插入功能
2.明确插入什么功能
3.明确在哪些方法上插入该功能
3.配置开发准备工作:
1.jar包 ① spring-context.jar ② aspectjweaver.jar
2.命名空间 ① context ② aop
3.切面类 类+方法(增加的功能)
4.完成织入:
//
<aop:config>
<!--引用myAspect的Bean为切面对象--> --确定切面类
<aop:aspect ref="myAspect">
<!--配置Target的method方法执行时要进行myAspect的before方法前置增强-->
<① aop:before ② method="before" ③ pointcut="execution(public void com.itheima.aop.Target.method())"/>
----1.插入方式 2.插入的增强的功能 3.对哪些目标方法插入
</aop:aspect>
</aop:config>
4.配置详解
1. 切点表达式的详解 (printcut)
表达式语法:printcut=“ execution ( [修饰符] 返回值类型 包名.类名.方法名(参数))”
1.修饰符可不写
2.返回值,包名,类名,方法名,可以用*代替,任意。
3.参数 用 .. 表示
2.通知的类型(Advice)
通知的配置语法:<aop:通知类型 method=“切面类中方法名” pointcut=“切点表达式"></aop:通知类型>
1.前置增强: aop:before 在目标方法执行前 切入方法
2.返回增强:aop:afterReturnning 在目标方法后 切入方法
3.后置增强:aop:after 不管目标方法是否执行报错,都会在后面 把增强方法执行了。
4.异常增强: aop:afterThrowing 当目标对象发生异常或错误时执行的切入的方法。如果无异常就不执行了。
5.环绕增强:aop:around 将目标方法放入切入的方法
切面类的切入的方法:
在方法参数位置 传递 ProceedingJoinPoint 对象
在方法执行过程中 执行目标方法 ProceedingJoinPoint.proceed();
目标方法有返回值就返回,无返回该方法也无返回
/*public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕前增强");
//正在进行的切点proceeding JoinPoint 表示原来target的方法 目标方法执行
Object proceed = proceedingJoinPoint.proceed();
System.out.println("环绕后增强");
return proceed;
}
*/
3. 切点表达式的抽取
当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用 pointcut-ref
属性代替 pointcut 属性来引用抽取后的切点表达式。
----当某些固定目标方法的功能 需要统一增强 某些方法时。
我们把这些目标方法的切点表达式提取出来,用增强方法挨个引入切点表单式。
1.提取一个切点表达式 用id = “myPointcut” 命名 。后面的pointcut 可以引入这个id
<aop:pointcut id="myPointcut" expression="execution(* com.itheima.aop.*.*(..))"/>
2.使用 pointcut - ref 代替pointcut 引用过来专门的切点表单式
<aop:before method="before" pointcut-ref="myPointcut"></aop:before>
#Spring-AOP 注解开发
1.@Aspect:标注切面类
2.增强方式:标注在通知方法上
1.@Before("切点表达式")
2.@AfterReturnning("切点表达式")
3.@Around("切点表达式")
4.@AfterThrowing(“切点表达式”)
5.@after(“切点表达式”)
一般以上使用注解开发,便于开发。