理解AOP相关概念

Target(目标对象):代理的目标对象

Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.(目标对象中,所有可以增强的方法)

Pointcut(切入点/切点):所谓切入点是指我们要对哪些Joinpoint进行拦截(目标对象中,确定要增强的方法).

Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(增强的代码)

Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.(将通知应用到切点的过程)

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类(将通知织入到目标对象之后,形成代理)

Aspect(切面): 是切入点和通知的结合(切点+通知)

一个线是一个特殊的面。

一个切入点和一个通知,组成成一个特殊的面。

注意:通知有:  前置通知,后置通知(出现异常不会调用),环绕通知,异常拦截通知,后置通知(出现异常会调用)

Spring AOP 编程

从spring容器获得目标类,如果配置aop,spring将自动生成代理。

导入jar包spring-framework-3.0.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE

第一种基于xml配置

1.配置通知


public class MyAdvice { //前置通知
public void before(){
System.out.println("前置通知");
}
//后置通知 出现异常不会调用
public void afterreturning(){
System.out.println("后置通知,出现异常不会调用");
}
//环绕通知
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕之前的部分");
Object obj = pjp.proceed();//调用原方法
System.out.println("环绕之后的部分");
return obj;
}
//异常拦截通知
public void afterException(){
System.out.println("出现异常");
}
//后置通知(出现异常会调用)
public void after(){
System.out.println("后置通知(出现异常会调用)");
}
}

2.配置applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<!-- aop -->
<!-- 配置目标对象 -->
<bean name="userService" class="com.service.userServiceImpl"></bean>
<!-- 配置通知 -->
<bean name="myAdvice" class="com.aop.MyAdvice"></bean>
<!-- 配置通知织入到目标对象的方法 -->
<aop:config>
<!-- 配置切入点 即要增强那个方法 -->
<!-- 方法书写规则:
com.service.UserServiceImpl.save()
* com.service.UserServiceImpl.*(..)
* com.service.*.*(..)
-->
<!--切点-->
<aop:pointcut expression="execution(public void com.service.userServiceImpl.save())" id="poincut"/>
<!-- 切面 -->
<aop:aspect ref="myAdvice">
<aop:after method="after" pointcut-ref="poincut"/>
<aop:after-returning method="afterreturning" pointcut-ref="poincut"/>
<aop:after-throwing method="afterException" pointcut-ref="poincut"/>
<aop:around method="around" pointcut-ref="poincut"/>
<aop:around method="before" pointcut-ref="poincut"/>
</aop:aspect>
</aop:config> </beans>

测试类demo

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/aop/aop.xml")
public class Demo {
@Resource(name = "userService")
private userService userService; @Test
public void test(){
userService.save();
} }

第二种基于Annotation配置

1.配置通知

@Component("myAdvice")
@Aspect
public class MyAdvice {
@Pointcut("execution(* com.service.userServiceImpl.*())")
public void pc(){}
//前置通知
@Before("MyAdvice.pc()")
public void before(){
System.out.println("前置通知");
}
//后置通知 出现异常不会调用
@AfterReturning("MyAdvice.pc()")
public void afterreturning(){
System.out.println("后置通知,出现异常不会调用");
}
//环绕通知
@Around("execution(* com.service.userServiceImpl.*())")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕之前的部分");
Object obj = pjp.proceed();//调用原方法
System.out.println("环绕之后的部分");
return obj;
}
//异常拦截通知
@AfterThrowing("execution(* com.service.userServiceImpl.*())")
public void afterException(){
System.out.println("出现异常");
}
//后置通知(出现异常会调用)
@After("execution(* com.service.userServiceImpl.*())")
public void after(){
System.out.println("后置通知(出现异常会调用)");
}
}

2.配置applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- aop -->
<!-- 配置目标对象 -->
<bean name="userService" class="com.service.userServiceImpl"></bean>
<!-- 配置通知-->
<bean name="myAdvice" class="com.aopanotation.MyAdvice"></bean>
<!-- 使用注解-->
<context:component-scan base-package="com"></context:component-scan>
<!-- 配置通知织入到目标对象的方法 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

测试代码demo

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/aopanotation/aop.xml")
public class Demo1 {
@Resource(name = "userService")
private userService userService; @Test
public void test(){
userService.delete();
} }

@AspectJ 简介

1.AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持

2.@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面

新版本Spring框架,建议使用AspectJ方式来开发AOP

使用AspectJ 需要导入Spring AOP和 AspectJ相关jar包

spring-aop-3.2.0.RELEASE.jar

com.springsource.org.aopalliance-1.0.0.jar

spring-aspects-3.2.0.RELEASE.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

AOP切入点表达式:execution(掌握)

AOP切入点表达式支持多种形式的定义规则

•完整写法

返回类型  类的路径     类名   函数名 参数类型(用,分开)

execution(String com.chinasofti.Target.save(String))

•任意返回类型

execution(* com.chin.Target.save(String))

•任意返回类型下指定包下任意类

execution(* com.chin.*.save(String))

•任意返回类型下指定包下任意类任意函数

execution(* com.chin.*.*(String))

•任意返回类型下指定包或子包下任意类任意函数任意参数

execution(* com..*.*(..))

AOP通知类型

before:前置通知(应用:各种校验)

在方法执行前执行,如果通知抛出异常,阻止方法运行

afterReturning:后置通知(应用:常规数据处理)

方法正常返回后执行,如果方法中抛出异常,通知无法执行

必须在方法执行后才执行,所以可以获得方法的返回值。

around:环绕通知(应用:十分强大,可以做任何事情)

方法执行前后分别执行,可以阻止方法的执行

afterThrowing:抛出异常通知(应用:包装异常信息)

方法抛出异常后执行,如果方法没有抛出异常,无法执行

after:最终通知(应用:清理现场)

方法执行完毕后执行,无论方法中是否出现异常

AOP核心组件

切面(Aspect):切面是封装通用业务逻辑的组件,可以作用到其他组件上。

切入点(Pointcut):用于指定哪些组件哪些方法使用切面组件,Spring提供表达式来实现该指定。

通知(Advice):用于指定组件作用到目标组件的具体位置。

AOP前置通知:在目标组件的方法执行前执行的程序。

完成AOP的步骤

切入点程序。

切面程序。

通过配置文件将切面程序插入到切入点程序的某个位置上(通知)

补充:jar包

1.aop联盟规范

2.spring aop 实现

3.aspect 规范

4.spring aspect 实现

05_Spring AOP原理的更多相关文章

  1. spring ioc aop 原理

    spring ioc aop 原理 spring ioc aop 的原理 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分. 在传统的程序设计中,当调 ...

  2. SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

    接上一篇 SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP 本文采用强制的CGLB代理方式 Security ...

  3. SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

    AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...

  4. 面试问烂的 Spring AOP 原理、SpringMVC 过程(求求你别问了)

    Spring AOP ,SpringMVC ,这两个应该是国内面试必问题,网上有很多答案,其实背背就可以.但今天笔者带大家一起深入浅出源码,看看他的原理.以期让印象更加深刻,面试的时候游刃有余. Sp ...

  5. spring MVC 及 AOP 原理

    SpringMVC工作原理https://www.cnblogs.com/xiaoxi/p/6164383.htmlspring MVC 原理https://blog.csdn.net/y199108 ...

  6. spring aop 原理学习

    @EnableAspectJAutoProxy: @Import(AspectJAutoProxyRegistrar.class) 实际是创建了一个以org.springframework.aop.c ...

  7. Spring之AOP原理、代码、使用详解(XML配置方式)

    Spring 的两大核心,一是IOC,另一个是AOP,本博客从原理.AOP代码以及AOP使用三个方向来讲AOP.先给出一张AOP相关的结构图,可以放大查看. 一.Spring AOP 接口设计 1.P ...

  8. 34、[源码]-AOP原理-链式调用通知方法

    34.[源码]-AOP原理-链式调用通知方法

  9. 33、[源码]-AOP原理-获取拦截器链-MethodInterceptor

    33.[源码]-AOP原理-获取拦截器链-MethodInterceptor

随机推荐

  1. java 对象转Map方法Demo

    /** * 用于对Object进行解析并且转换成Map键值对的形式 * */ public class ObjectUtils { private static final String JAVAP ...

  2. Python学习笔记(一)——输入与输出

    输出:——print() Python中的输出使用print()完成 >>> 在屏幕中输出Hello World >>> print('Hello World') ...

  3. 廖雪峰Java15JDBC编程-3JDBC接口-5JDBC连接池

    1. JDBC连接池 1.1 JDBC连接池简介 线程池可以复用一个线程,这样大量的小任务通过线程池的线程执行,就可以避免反复创建线程带来的开销. 同样JDBC可以复用一个JDBC连接 JDBC的连接 ...

  4. 线段树+欧拉函数——cf1114F

    调了半天,写线段树老是写炸 /* 两个操作 1.区间乘法 2.区间乘积询问欧拉函数 欧拉函数计算公式 phi(mul(ai))=mul(ai) * (p1-1)/p1 * (p2-1)/p2 * .. ...

  5. springboot启动报 A child container failed during start 错误解决过程

    启动结果如下: "C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" -agentlib:jdwp=transport=dt_sock ...

  6. SP1296 SUMFOUR - 4 values whose sum is 0

    传送门 解题思路 四个数组一起做有点炸.先把他们合并成两个数组,然后让一个数组有序,枚举另一个数组的元素,二分即可.时间复杂度\(O(n^2logn^2)\) 代码 #include<iostr ...

  7. react 16更新

    1.render新的返回类型 render方法支持两种新的返回类型:数组(由React元素组成)和字符串 2.错误处理 16之前,组件在运行期间如果执行出错,就会阻塞整个应用的渲染,这时候只能刷新页面 ...

  8. Codeforces-GYM101873 G Water Testing 皮克定理

    题意: 给定一个多边形,这个多边形的点都在格点上,问你这个多边形里面包含了几个格点. 题解: 对于格点多边形有一个非常有趣的定理: 多边形的面积S,内部的格点数a和边界上的格点数b,满足如下结论: 2 ...

  9. IDEA 创建普通的maven+java Project

    最近想把以前积累的零散java练习和学习的东西建一个项目整理出来上传到码云托管,免得电脑挂了啥也找不到 配置是IDEA2017+java8+maven3.2.5,截图记录下步骤 第一步:File--& ...

  10. JDK9新特性实战:简化流关闭新姿势。

    做Java开发的都知道,每个资源的打开都需要对应的关闭操作,不然就会使资源一直占用而造成资源浪费,从而降低系统性能. 关于资源的关闭操作,从JDK7-JDK9有了不少的提升及简化. JDK6 在JDK ...