sring aop的方式有两种:(1)xml文件配置方式(2)注解的方式实现,我们可以先通过一个demo认识spring aop的实现,然后再对其进行详细的解释。

一、基于注解的springAop配置。

  环境准备阶段:

  (1)pom.xml:

 <dependencies>
<!-- 引入Spring-AOP等相关Jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency> <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency> <!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>

 (2)定义接口:

 package cn.spring.aop.dao;

 /**
* @author Simple
* @date 10:01 2019/8/20
* @description
*/
public interface UserService {
public void save();
}

 (3)接口实现类:

 package cn.spring.aop.dao;

 import org.springframework.stereotype.Service;

 /**
* @author Simple
* @date 9:57 2019/8/20
* @description
*/
@Service
public class UserServiceImpl implements UserService { @Override
public void save() {
System.out.println("保存成功.....");
}
}

 (4)Aop类: 

 package cn.spring.aop;

 import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component; /**
* @author Simple
* @date 10:06 2019/8/20
* @description
*/
@Component
@Aspect
public class AopAspect {
/**
* 前置通知
*/
@Before("execution(* cn.spring.aop.dao.UserService.save(..))")
public void before(){
System.out.println("前置通知....");
} /**
* 后置通知
* returnVal,切点方法执行后的返回值
*/
@AfterReturning(value="execution(* cn.spring.aop.dao.UserService.save(..))",returning = "returnVal")
public void AfterReturning(Object returnVal){
System.out.println("后置通知...."+returnVal);
} /**
* 环绕通知
* @param joinPoint 可用于执行切点的类
* @return
* @throws Throwable
*/
@Around("execution(* cn.spring.aop.dao.UserService.save(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知前....");
Object obj= (Object) joinPoint.proceed();
System.out.println("环绕通知后....");
return obj;
} /**
* 抛出通知
* @param e
*/
@AfterThrowing(value="execution(* cn.spring.aop.dao.UserService.save(..))",throwing = "e")
public void afterThrowable(Throwable e){
System.out.println("出现异常:msg="+e.getMessage());
} /**
* 无论什么情况下都会执行的方法
*/
@After(value="execution(* cn.spring.aop.dao.UserService.save(..))")
public void after(){
System.out.println("最终通知....");
}
}

 (5)spring.xml

 <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"
xmlns:context="http://www.springframework.org/schema/context"
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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="cn.spring.aop"></context:component-scan>
<!-- 启动@aspectj的自动代理支持-->
<aop:aspectj-autoproxy />
</beans>

 (6)测试类:

 package cn.spring.aop;

 import cn.spring.aop.dao.UserService;
import cn.spring.aop.dao.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author Simple
* @date 10:13 2019/8/20
* @description
*/
public class TestDemo {
public static void main(String[] args) {
ApplicationContext ac =new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) ac.getBean("userServiceImpl");
userService.save();
}
}

 (7)运行结果:

二、配置详解

(1)spring.xml中注解的作用

1.spring--<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

   这个是 开启事物注解权限,引入了三个jar包  aspectjweaver.jar aspectjrt.jar aspectj.jar  aopalliance.jar。

  2.Spring -- <context:component-scan>

   在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean。

(2)Aop类中的注解

在aop类中,编写了5种注解类型的通知函数:

   @Before 前置通知

   @AfterReturning 后置通知

   @Around 环绕通知

   @AfterThrowing 异常通知

   @After 最终通知

   @pointcut 定义切点匹配表达式

(3)切点表达式

  1. execution

   由于Spring切面粒度最小是达到方法级别,而execution表达式可以用于明确指定方法返回类型,类名,方法名和参数名等与方法相关的部件,并且在Spring中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用是最为广泛的。如下是execution表达式的语法:

 execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

 这里问号表示当前项可以有也可以没有,其中各项的语义如下:
  • modifiers-pattern方法的可见性,如public,protected;
  • ret-type-pattern:方法的返回值类型,如int,void等;
  • declaring-type-pattern:方法所在类的全路径名,如com.spring.Aspect;
  • name-pattern:方法名类型,如buisinessService();
  • param-pattern:方法的参数类型,如java.lang.String;
  • throws-pattern:方法抛出的异常类型,如java.lang.Exception;

如下是一个使用execution表达式的例子:

  execution(public * com.spring.service.BusinessObject.businessService(java.lang.String,..))

上述切点表达式将会匹配使用public修饰,返回值为任意类型,并且是com.spring.BusinessObject类中名称为businessService的方法,方法可以有多个参数,但是第一个参数必须是java.lang.String类型的方法。

   通配符的类型,主要有两种:

  • *通配符,该通配符主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词。

如下示例表示返回值为任意类型,在com.spring.service.BusinessObject类中,并且参数个数为零的方法:execution(* com.spring.service.BusinessObject.*())

  • ..通配符,该通配符表示0个或多个项,主要用于declaring-type-pattern和param-pattern中,如果用于declaring-type-pattern中,则表示匹配当前包及其子包,如果用于param-pattern中,则表示匹配0个或多个参数。

如下示例表示匹配返回值为任意类型,并且是com.spring.service包及其子包下的任意类的名称为businessService的方法,而且该方法不能有任何参数:execution(* com.spring.service..*.businessService())

这里需要说明的是,包路径service..*.businessService()中的..应该理解为延续前面的service路径,表示到service路径为止,或者继续延续service路径,从而包括其子包路径;后面的*.businessService(),这里的*表示匹配一个单词,因为是在方法名前,因而表示匹配任意的类。

如下示例是使用..表示任意个数的参数的示例,需要注意,表示参数的时候可以在括号中事先指定某些类型的参数,而其余的参数则由..进行匹配:

execution(* com.spring.service.BusinessObject.businessService(java.lang.String,..))

三、基于xml的SpringAop配置

  xml配置主要是将注解转换为xml这里我们在上述的情况下做下修改,主要修改两个地方:1,spring.xml,2 aop类

1.springaop.xml

 <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"
xmlns:context="http://www.springframework.org/schema/context"
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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--基于配置需要我们手动进行配置-->
<!-- dao 实例 -->
<bean id="userService" class="cn.spring.aop.dao.UserServiceImpl"></bean>
<!-- 切面类 -->
<bean id="aop" class="cn.spring.aop.AopAspect2"></bean>
<!-- Aop配置 -->
<aop:config>
<!-- 定义一个切入点表达式: 拦截哪些方法 -->
<aop:pointcut expression="execution(* cn.spring.aop.dao.UserService.*(..))" id="pt"/>
<!-- 切面 -->
<aop:aspect ref="aop">
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pt"/>
<!-- 前置通知: 在目标方法调用前执行 -->
<aop:before method="before" pointcut-ref="pt"/>
<!-- 后置通知: -->
<aop:after method="after" pointcut-ref="pt"/>
<!-- 返回后通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="pt" />
<!-- 异常通知 -->
<aop:after-throwing method="after" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
</beans>

 2.aop类  AopAspect2

 package cn.spring.aop;

 import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component; /**
* @author Simple
* @date 10:06 2019/8/20
* @description
*/
@Component
@Aspect
public class AopAspect2 {
/**
* 前置通知
*/
public void before(){
System.out.println("前置通知....");
} /**
* 后置通知
* returnVal,切点方法执行后的返回值
*/
public void afterReturning(){
System.out.println("后置通知....");
} /**
* 环绕通知
* @param joinPoint 可用于执行切点的类
* @return
* @throws Throwable
*/
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知前....");
Object obj= (Object) joinPoint.proceed();
System.out.println("环绕通知后....");
return obj;
} /**
* 抛出通知
* @param e
*/
public void afterThrowable(Throwable e){
System.out.println("出现异常:msg="+e.getMessage());
} /**
* 无论什么情况下都会执行的方法
*/
public void after(){
System.out.println("最终通知....");
}
}

 3.测试方法

 package cn.spring.aop;

 import cn.spring.aop.dao.UserService;
import cn.spring.aop.dao.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author Simple
* @date 10:13 2019/8/20
* @description
*/
public class TestDemo {
public static void main(String[] args) {
ApplicationContext ac =new ClassPathXmlApplicationContext("springaop.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.save();
}
}

 4.运行结果

现在在开发中主要是使用注解进行开发,方便快捷,但是更多的是配置和注解一块使用,springaop在配置方面很多都是这种注解加配置,原因主要是方便管理维护。我们这里主要讲的是两种方式的使用和切点表达式。

(一)spring aop的两种配置方式。的更多相关文章

  1. spring AOP的两种配置方式

    连接点(JoinPoint) ,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的前.后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点.其他 ...

  2. spring ----> aop的两种实现方式

    实现1:基于xml package com.rr.spring3.interf; //接口 public interface SayHello { public void sayHello(); } ...

  3. spring AOP的两种配置

    xml配置 定义要被代理的方法的接口 public interface TestAop { public void print(String s); } 实现上述接口 public class Tes ...

  4. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  5. hibernate 一对一 one to one的两种配置方式

    hibernate中one-to-one两种配置方式 标签: hibernateHibernateone-to-one 2013-02-19 17:44 11445人阅读 评论(1) 收藏 举报  分 ...

  6. spring AOP的两种代理

    本篇记录下spring AOP的两种代理,为下一篇AOP实现做下铺垫. 1.JDK动态代理  2.cglib代理 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP2.如果目标对象 ...

  7. Hibernate中双向多对多的两种配置方式

    Hibernate中双向多对多的两种配置方式 1.建立多对多双向关联关系 package cn.happy.entitys; import java.util.HashSet; import java ...

  8. spring Bean的三种配置方式

    Spring Bean有三种配置方式: 传统的XML配置方式 基于注解的配置 基于类的Java Config 添加spring的maven repository <dependency> ...

  9. 学习JavaWeb aop两种配置方式

    aop aop:面向切面编程,它可以解决重复代码. aop有两种方式: 一..xml方式 1.在springmvc-servlet.xml中配置aop,应用bean文件: <!--aop配置-- ...

随机推荐

  1. TCP传输协议如何进行拥塞控制?

    拥塞控制 拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象.这种现象跟公路网中 ...

  2. 【Android】Jetpack中的ViewModel:自动保存页面数据

    目录 ViewModel 简介 ViewModel的使用方法 ViewModel 简介   ViewModel 允许数据在配置更改(如屏幕旋转)后仍然存在,使用 ViewModel 可以免去开发者花费 ...

  3. 记kepServer读写西门子PLC

    在程序开发过程中为了测试方法或者验证某个属性的值是否正确 经常通过Kepserver 的 OPC Quick Client来手动置点或者读取点位 例如 这里显示的值都是经过转化后得到的十进制值,那我们 ...

  4. idea使用大全(加载mysql驱动)

    1.载入mysql驱动 找到项目结构(project structure) 选Modules 找到右边的加号选择第一个 OK

  5. 【Java例题】7.6文件题3-文本文件统计

    6.文本文件统计.已有一个文本文件文件,请统计数字.大写字母.小写字母.汉字及其它字符出现的次数:然后将这些次数由大到小写到另一个文件之中.说明:将次数为零的过滤掉排序 package chapter ...

  6. 【简洁易懂】CF372C Watching Fireworks is Fun dp + 单调队列优化 dp优化 ACM codeforces

    题目大意 一条街道有$n$个区域. 从左到右编号为$1$到$n$. 相邻区域之间的距离为$1$. 在节日期间,有$m$次烟花要燃放. 第$i$次烟花燃放区域为$a_i$ ,幸福属性为$b_i$,时间为 ...

  7. gRPC的简单使用

    目录 前言 gRPC的简单介绍 基本用法 服务的定义 服务端代码编写 客户端代码编写 运行效果 服务治理(注册与发现) .NET Core 2.x 和 .NET Core 3.0的细微区别 扩展阅读 ...

  8. 洛谷 P1631 序列合并

    题意简述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. 题解思路 大根堆,先存入n个和,再比较大小,改变堆中元素. 代码 #include & ...

  9. Nginx在linux下安装及简单命令

    安装环境:Centos7 创建目录及切换至目录 # mkdir /usr/local/nginx # cd /usr/local/nginx/ 下载nginx包,访问http://nginx.org下 ...

  10. HTTP请求包和响应包

    HTTP请求包 HTTP响应包