SpringAOP面向编程

什么是AOP

AOP是一种能在程序运行时,将我们的横切性关注点方法动态的织入到指定类的指定方法上,对我们的目标方法在执行前后进行代码增强,这就是面向切面的编程思想,是对传统的面向对象的一种补充。Spring的AOP分为静态AOP和动态的AOP,Spring底层为动态AOP提供了两种实现方法,jdk动态代理和cglib代理,其中jdk动态代理是基于接口实现的,而cglib代理是基于继承实现的。虽然这两种代理在实现方式上略有不同,但其本质都是使用代理模式,为目标类生成代理对象,通过代理对象在调用目标方法的前后做一些额外的操作,从而实现我们目标方法的增强。

手动编写代理

在之前我们要为一个类生成代理对象,需要自己手动编写代码来实现,具体是通过Proxy.newProxyIntance()来返回代理类的代理对象,其中传入的参数有三个,第一个是代理类对象,第二个是代理类所实现的接口,第三个是一个InvocationHandler类型的对象,在这个对象中有一个invoke()方法,这个方法的具体作用就是代理要做的事情。下面来看看具体的实现。
首先需要准备四个类:接口、接口实现、代理类以及测试类
1、创建接口

public interface UserService {
 public void insert();//插入用户
}

2、创建接口实现类

public class UserServiceImpl implements UserService{
 @Override
 public void insert() {
  System.out.println("do insert......");
 }
}

3、创建生成代理的类


public class UserProxy implements InvocationHandler{
 private Object object;//目标对象
 public UserProxy(Object obj){
  object=obj;
 }
 public Object getProxyIntance(){
  
  return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);//返回代理对象
 }
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  System.out.println("打开事务");
  Object invoke = method.invoke(object, args);//代理类调用真正的方法
  System.out.println("关闭事务");
  return invoke;
 }
}

4、测试类

public class ProxyTest {
 public static void main(String[] args) {
  UserService userService=new UserServiceImpl();
  UserProxy userProxy = new UserProxy(userService);//将代理对象传递进去
  UserService intance = (UserService) userProxy.getProxyIntance();//获得代理对象
  intance.insert();//这里调用的只是代理对象中的方法,真正的方法是在代理对象内部代用的
 }
}

运行结果:
在这里插入图片描述

Spring AOP实现代码增强

首先spring aop实现代码增强的本质上也是通过代理来实现的,使用aop来实现代理就不用我们自己手动编写像上述那样的代理类了。只需通过简单的配置或者注解声明的方法就能为我们的目标方法进行代码增强,其底层对自动根据我们的目标类来决定使用jdk动态代理还是cglib代理。
aop中的相关名词解释
1、join point:连接点,所有能用来增强的方法
2、point cut:切入点,想要增强的方法
3、advice:通知(增强),为我们的目标方法的额外操作的方法
4、waving:织入,将我们的通知织入到切入点的动作
5、aspect:切面,通知+切入点

spring aop中提供了五种通知的类型,在四种通知类型会在我们的目标方法调用时,在不同的时机进行自动调用从而增强目标方法 的功能。
1、前置通知:目标方法执行前执行
2、环绕通知:目标方法执行前后执行,需要在此通知中手动调用我们的目标方法。
3、后置通知:目标方法执行后执行,出现异常则不会调用
4、异常通知:目标方法执行过程中有异常则执行
5、最终通知:在目标方法调用后,无论如何都会执行

下面进行案例演示:
1、接口及接口实现类

public interface UserService {
 public void insert();
}

public class UserServiceImpl implements UserService {
 @Override
 public void insert() {
  System.out.println("insert is running.......");
  //int a=1/0;
 }
}

2、增强类

public class MyAdvice {
 
 //前置通知
 public void before(){
  System.out.println("前置通知:开启事务");
 }
 
 //后置通知,出现异常时不会执行
 public void after(){
  System.out.println("后置通知:关闭事务");
 }
 
 //出现异常时执行
 public void throwing(){
  System.out.println("异常通知:出现异常啦");
 }
 
 //环绕通知
 public Object arount(ProceedingJoinPoint pjp) throws Throwable{
  System.out.println("环绕通知前部分");
  Object proceed = pjp.proceed();//调用目标方法
  System.out.println("环绕通知后部分");
  return proceed;
 }
  //最终通知,目标方法执行后无论如何都会执行
 public void finaled(){
  System.out.println("最终通知:关闭资源部");
 }
}

3、xml配置

<?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-3.2.xsd
               http://www.springframework.org/schema/aop 
      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
 <!-- 配置目标类 -->
 <bean class="SpringAopTest.UserServiceImpl" id="userService"></bean>
 
 <!-- 配置增强类 -->
 <bean class="SpringAopTest.MyAdvice" id="myAdvice"></bean>
 
 <!-- 织入的过程,将增强切入到指定的切入点中 -->
 <aop:config>
  <!-- 配置切入点 -->
  <aop:pointcut expression="execution(* SpringAopTest.UserServiceImpl.insert())" id="pc"/>
  <!-- 配置切面 -->
  <aop:aspect ref="myAdvice">
   <!-- 前置通知 -->
   <aop:before method="before" pointcut-ref="pc"/>
   <!-- 异常通知-->
   <aop:after-throwing method="throwing" pointcut-ref="pc"/>
   <!-- 最终通知 :无论是否出现异常都执行-->
   <aop:after method="finaled" pointcut-ref="pc"/>
   <!-- 后置通知:出现异常不执行 -->
   <aop:after-returning method="after" pointcut-ref="pc"/>
   <!-- 环绕通知  -->
   <aop:around method="arount" pointcut-ref="pc"/>
  </aop:aspect>
 </aop:config>
</beans>

4、测试类

public class AopTest {
 @SuppressWarnings("resource")
 public static void main(String[] args) {
  ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("SpringAopTest/ApplicationContent.xml");
  UserService userService = (UserService) applicationContext.getBean("userService");
  userService.insert();
 }
}

5、执行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值