手写Spring的事务框架,SpringAOP的技术你们用过没有,Spring事务分为两种,一种叫编程式事务,一种叫声明式事务,我讲一下SpringAOP的技术怎么用,项目jar包依赖信息,因为我们会用到数据源,要做事务处理,第一步把所有的jar包copy进来
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.learn</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><!-- https://mvnrepository.com/artifact/javassist/javassist --><dependency><groupId>javassist</groupId><artifactId>javassist</artifactId><version>3.12.1.GA</version></dependency><!-- 引入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></dependencies></project>
是简单的搭建一个Spring的环境,事务,AOP,因为我们待会会用到的,然后在这个地方我们就来做个操作,给他简单的用一下Spring的AOP,有两种实现方式,在SpringAOP的技术里面,一种叫做注解版本,还有一种是XML版本,我告诉你们,我一般是用注解版本的,很多去用xml版本的,为什么呢,因为你们以后会学一个SpringBoot的,你们以后尽量不要写xml,因为你们发现用SpringBoot的时候,你根本就不写xml了,全都是自动化的,全部都是注解版本的,所以我们讲一下,xml版本我相信,在今后几年当中,都会淘汰的,通过注解方式替代xml方式,今天我主要讲注解版本,不去讲xml版本了,你们可以自己去看看,我就不说了,那怎么去用呢,这个用法就比较简单,大家想一下AOP的几个点,然后我再去讲一下代码如何去整合,然后在这里给大家说一下
package com.learn.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;/*** 做一个日志的处理* 这个类干嘛的呢* 其实就是切面类* 把我们重复的代码全部放在AOP里面去* 这个代码怎么写* 首先记住这里加一个注解* @Apect表示这是一个切面类了* 然后放在容器里面去的@Component* * @author Leon.Sun**/
@Component
@Aspect
public class AogLog {/*** 在这里我们怎么去做处理呢* 首先这里有几个方法一定要认真听一下* SpringAOP里面有几个通知* 第一个叫前置通知* 还有一个叫后置通知* 还又叫运行通知* 还有叫异常通知* 环绕通知* 我一个个讲* * 这个通知我们就叫做前置通知* * 前置通知到底是干嘛目的* 你要写一个表达式* 切入点的表达式* 这是我要给你们说一下* 切入点是啥意思* 假如你要拦截哪些方法* "execution(* com.learn.service.UserService.add(..))"* 你们看一下是什么意思啊* 这个表达式是做什么目的的* 表示我会去拦截com.learn.service.UserService这个类的add的方法* 我会在这个方法之前做一个拦截* 这个方法叫前置通知* */@Before("execution(* com.learn.service.UserService.add(..))")public void before() {/*** 在方法之前执行* */System.out.println("前置通知 在方法之前执行...");}/*** 我们在这里可以写一个后置通知* 这个叫后置通知* 后置通知里我要怎么去写呢* 这个我们怎么写* 后置通知 在方法运行后执行* "execution(* com.learn.service.UserService.add(..))"* 我把这个表达式也copy过来*/@After("execution(* com.learn.service.UserService.add(..))")public void after() {/*** 在方法后执行*/System.out.println("后置通知 在方法之后执行...");}/*** 我依次类推* 运行通知* 首先这个通知是干嘛用的* 就是方法运行的时候就有这个通知*/@AfterReturning("execution(* com.learn.service.UserService.add(..))")public void returning() {System.out.println("运行通知");}/*** 这个表示在方法异常的情况下会有异常通知的* 大家不要小看异常通知* 为什么Spring事务为什么会失效呢* 就是我没有注意异常* 我待会会细说的* * */@AfterThrowing("execution(* com.learn.service.UserService.add(..))")public void afterThrowing() {System.out.println("异常通知");}/*** 这个也是我们会经常用的环绕通知* 环绕通知里面是怎么写的呢* 环绕通知 在方法之前和之后处理事情* ProceedingJoinPoint传进来* 这个方法怎么用的呢* 就好比他在实际调用你的add方法* * 其实你们可以把表达式抽取出来* 我先这样写* 你们可以把表达式封装成一个* 这也是可以的* * * @param proceedingJoinPoint* @throws Throwable*/@Around("execution(* com.learn.service.UserService.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{/*** 调用方法之前执行*/System.out.println("环绕通知 调用方法之前执行");/*** 这里有一个方法* 代理调用方法 注意点: 如果调用方法抛出溢出不会执行后面代码* 相当于invoke* 这个方法非常核心* 你们使用Spring事务的时候为什么会失效呢* 如果没有抛出这个异常* 如果你的调用方法抛出异常* 假设你抛出异常的情况下* 他就会怎么样进行处理呢* 不会执行后面的代码* 这是什么意思啊* 比如代理调用方法的时候* 假设去调用add方法的时候* 如果add方法里面突然报了一个错* 他就不会往后面继续执行的* 这是我要给你们说的* 所以你们使用事务的时候不要去try* 一定要抛出去* 抛的话会导致什么问题呢* 事务提交到数据库里面去了* 你这样会回滚的* 那肯定不好*/proceedingJoinPoint.proceed();/*** 调用方法之后执行*/System.out.println("环绕通知 调用方法之后执行");}
}
<?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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 这里表示扫包范围 因为我们是使用注解的,--><context:component-scan base-package="com.learn"></context:component-scan><!-- 这里表示开启事务的注解 你如果想要事务的话,你必须开启一个事务注解,--><aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 开启事物注解 --><!-- 1. 数据源对象: C3P0连接池 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property><property name="user" value="root"></property><property name="password" value="root"></property></bean><!-- 2. JdbcTemplate工具类实例 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!-- 3.配置事务 --><bean id="dataSourceTransactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean></beans>
package com.learn.service.impl;import org.springframework.stereotype.Service;import com.learn.service.UserService;/*** 加上注解之后* @author Leon.Sun**/
@Service
public class UserServiceImpl implements UserService {public void add() {try {int i = 10 /0;System.out.println("################往数据库添加数据#################");} catch (Exception e) {}}}
package com.learn.service;public interface UserService {public void add();
}
package com.learn.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.learn.service.UserService;/*** 我们看一下AOP能不能成功* @author Leon.Sun**/
public class Test001 {public static void main(String[] args) {/*** new一下ClassPathXmlApplicationContext* 表示读取到我们的spring.xml配置文件* */ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");/*** 这样拿到我们的user接口* 把它强转一下* */UserService userService = (UserService) applicationContext.getBean("userServiceImpl");/*** 前置通知* 环绕通知之前* 往数据库里添加代码* 后置通知* 运行通知* 环绕通知之后* * 异常通知现在有没有运行过* 为什么* 因为我的方法没有抛异常* 怎么可能运行我的异常通知* 我在add方法里面写一个 int i = 10 /0* 写完之后我们看一下效果* 是不是报错了* 异常通知* 你们看一下环绕通知之后有没有再运行* 环绕通知之后就会打印这段代码* 有没有执行* 因为它报错了* 只要你调用的方法报错的情况下* 他不会执行的* 这边我就给你演示一个错误* * 比如我把它try一下* 这个时候环绕通知之后的代码会不会执行* 环绕通知之后会不会执行* 会还是不会* 这肯定会* 因为他没有把异常抛出来* 肯定是会的* 环绕方法调用之前和环绕方法调用之后* 这个时候就把注解版的事务讲完了* 还有xml方式我就不去讲了* * * */userService.add();}}//前置通知 在方法之前执行...
//环绕通知 调用方法之前执行
//################往数据库添加数据#################
//后置通知 在方法之后执行...
//运行通知
//环绕通知 调用方法之后执行//前置通知 在方法之前执行...
//Exception in thread "main" java.lang.ArithmeticException: / by zero
//  at com.learn.service.impl.UserServiceImpl.add(UserServiceImpl.java:16)
//  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
//  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
//环绕通知 调用方法之前执行
//后置通知 在方法之后执行...
//异常通知
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>  开启事物注解权限
@Aspect                            指定一个类为切面类
@Pointcut("execution(* com.itmayiedu.service.UserService.add(..))")  指定切入点表达式
@Before("pointCut_()")               前置通知: 目标方法之前执行
@After("pointCut_()")                后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()")        返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()")            异常通知:  出现异常时候执行
@Around("pointCut_()")               环绕通知: 环绕目标方法执行
XML方式实现AOPXml实现aop编程:1) 引入jar文件  【aop 相关jar, 4个】2) 引入aop名称空间3)aop 配置* 配置切面类 (重复执行代码形成的类)* aop配置拦截哪些方法 / 拦截到方法后应用通知代码
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- dao 实例 --><bean id="userService" class="com.learn.service.UserService"></bean><!-- 切面类 --><bean id="aop" class="com.learn.aop.AopLog"></bean><!-- Aop配置 --><aop:config><!-- 定义一个切入点表达式: 拦截哪些方法 --><aop:pointcut expression="execution(* com.learn.service.UserService.*(..))"id="pt" /><!-- 切面 --><aop:aspect ref="aop"><!-- 环绕通知 --><aop:around method="around" pointcut-ref="pt" /><!-- 前置通知: 在目标方法调用前执行 --><aop:before method="begin" pointcut-ref="pt" /><!-- 后置通知: --><aop:after method="after" pointcut-ref="pt" /><!-- 返回后通知 --><aop:after-returning method="afterReturning"pointcut-ref="pt" /><!-- 异常通知 --><aop:after-throwing method="afterThrowing"pointcut-ref="pt" /></aop:aspect></aop:config></beans>

使用springaop技术面向切面编程相关推荐

  1. SpringAop面向切面编程使用详解

    一.AOP概述 1.1 AOP的概念 AOP(Aspect Oriented Programing)面向切面编程. 它是一种编程范式,属于软工范畴,指导开发者如何组织程序结构. 它是是通过预编译方式和 ...

  2. JAVAEE框架整合技术之Spring02-AOP面向切面编程技术

    Spring新注解 Spring5.0之后的注解称为新注解 使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置 注解 说明 @Configuration 表示当前类是一个配置类,用于 ...

  3. springAOP面向切面编程以及对事务的支持

    目录 一.springAOP 面向切面编程 (一)springAOP概念解析 (二)springAOP的XML文件配置 1.入门案例 2.AOP的工作流程 3.通知类型 4.切点表达式 5.配置所有通 ...

  4. 【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术

    文章目录 一.Android 中的 Java 源码打包流程 1.Java 源码打包流程 2.字符串常量池 二.Android 中的字节码操作方式 一.Android 中的 Java 源码打包流程 Ja ...

  5. 五分钟学会 SpringAOP 面向切面编程

    SpringAOP 面向切面编程: 面向切面编程:将函数拦截做其他的事而不影响正常的业务流程. 出发点:核心代码与普通代码分离,减少重复代码,降低耦合度. 一,如何让spring项目支持面向切面编程: ...

  6. 【Spring】面向切面编程AOP

    AOP基础 什么是AOP [废话解释]在软件业,AOP全称Aspect Oriented Programming 即:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AO ...

  7. 面向切面编程-日志切面应用

    简介: AOP:面向切面编程,即拓展功能不通过修改源代码实现,采用横向抽取机制,取代了传统的纵向继承体系重复性代码.在运行期通过代理方式向目标类织入增强代码. Aspecj:Aspecj 是一个基于j ...

  8. 服务端第三次课程:面向切面编程AOP

    3:面向切面编程AOP 1:回顾 bean的组装方式 规划的装配 component autowired sacn是在configuration底下的 Java config 使用configurat ...

  9. Spring面向切面编程

           JAVA就业套餐课:https://edu.csdn.net/combo/detail/1230 第1章主要介绍了Spring管理实体对象的应用,通过ApplicationContext ...

最新文章

  1. Eclipse引入spring约束详细教程
  2. Leetcode 133. 克隆图 解题思路及C++实现
  3. 性能优越的轻量级日志收集工具,微软、亚马逊都在用!
  4. 来客推仿拼多多电商商城小程序源码
  5. 机器学习方向企业面试题(二)
  6. 线性代数的相关计算(numpy)
  7. 我问你as3中 0.2 + 0.1 ==?
  8. 行业观察:拐点已至!抛弃传统数据库,乘云而上!
  9. HDU3348 coins【贪心】
  10. javascript的table 对象 属性 方法
  11. Unity3D(四)Camera和SkyBox
  12. Javaweb 网上订餐系统
  13. 51单片机和52单片机区别是什么?51仿真器有必要买吗?
  14. 开关电源和家电电源常用电磁兼容(EMC)执行标准
  15. CentOS7镜像下载地址
  16. 2018年第九届蓝桥杯决赛JAVA B 题解(全)
  17. android横竖屏切换布局闪退,D10上旋转屏幕闪退怎么回事
  18. 一名优秀的数据分析师应该具备这10项关键技能
  19. 基于ABP和Magicodes实现Excel导出操作
  20. zk选举机制和分布式一致性原理

热门文章

  1. 【转】全排列算法非递归实现和递归实现
  2. XHTML学习笔记 Part2:核心元素
  3. rfid5-写成platform驱动
  4. Android项目开发实战—自定义左右菜单
  5. Java Bean Validation 最佳实践
  6. UVA 11038 How Many O's?
  7. update,options
  8. 打开MSN提示Windows Live Communication Platform遇到问题需要关闭错误的解决方法
  9. 经典正则表达式——常用的正则表达式
  10. PHP 6:PHP 基本数据类型