目录

实验目的:

实验内容:

一、了解AOP(简介)

相关开发术语:

二、了解aop两种代理方式

三、使用spring AOP代理实现:

1、创建项目,引入相关架包

2、创建目标接口和实现类

3、创建切面类

4、更改spring配置文件

5、编写测试类,进行测试

实验目的:

1.了解AOP的概念和使用

2.理解AOP中的切面以及通知

3.熟悉Spring中两种动态代理方式的区别

4.掌握基于代理类的AOP实现

实验内容:

一、了解AOP(简介)

AOP(Aspect Oriented Programming的缩写,意为:面向切面编程)思想最早是由AOP联盟组织提出的,Spring是使用这种思想最好的框架。

什么是面向切面变成呢?我们举个小栗子:

在一个和谐的小家庭里,我每天的任务就是学习,每当我饿了的时候我需要自己去买菜做饭洗碗刷碗,但是家里有了老妈就不一样了,妈妈可以给我买菜做饭洗碗刷碗,我的主要任务就是学习,我关心的就不是今天还要去买菜做饭,我饿了需要吃饭的时候老妈给我拿过来我就开吃,我不想吃饭就不吃。这也就是我们开发中常说的解耦合,你只需要专注自己的事就行。

Spring的AOP有自己的实现方式(非常繁琐),AspectJ是一个AOP的框架,Spring引入AspectJ作为自身AOP的开发

相关开发术语:

  • Joinpoint:连接点,可以被拦截到的点。(例如上例中的增删改查的方法,这些方法都可以被增强,便可称之为连接点)
  • Pointcut:切入点,真正被拦截到的点。(如上例中只对save方法进行了增强,save便称之为切入点)
  • Advice:通知、增强。(如上例中对save方法进行权限校验,权限校验(checkPri)的方法称为通知)
  • Introduction:引介。类层面的增强。
  • Target:被增强的对象。例如对UserDap增强,UserDao称为目标
  • Weaving:织入,将通知应用(Advice)到目标(Target)的过程。(如上例将权限校验的方法的代码应用到UserDao的save方法上的过程)
  • Proxy:代理对象
  • Aspect:切面,多个通知和多个切入点的组合

二、了解aop两种代理方式

 动态代理又分为两种:(实在不太了解去B站康康视频了解一哈)

一、JDK 动态代理:就是基于接口的动态代理,而不能针对类。代码实现如下:

1、首先创建接口UserDao并创建一个learn方法

public interface UserDao {public void learn();
}

2、它的实现类UserImpl

public class UserDaoImpl implements UserDao{@Overridepublic void learn() {System.out.println("我今天学习了加减乘除");}
}

3、使用JDK动态代理对UserDao产生代理:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JdkProxy implements InvocationHandler {//被代理的目标对象private UserDao userDao;public Object createProxy(UserDao userDao){this.userDao = userDao;//返回一个代理对象return Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),this);}/*** 执行目标对象 * Object  proxy:被代理的对象 * Method  method:要调用的方法 * Object  args[]:方法调用时所需要的参数 */@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();// 通过反射机制调用目标对象的方法  Object object = method.invoke(this.userDao,args);after();return object;}public void before(){System.out.println("孩子饿了吧,吃完饭再学习");}public void after(){System.out.println("让我考考你");}}

4、创建测试类TestJDK并运行

public class TestJDK {public static void main(String[] args) {// 要代理的真实对象UserDao userDao = new UserDaoImpl();userDao.learn();//没用代理System.out.println("-------------分隔线--------------");JdkProxy jdkProxy = new JdkProxy();UserDao userDaoProxy = (UserDao) jdkProxy.createProxy(userDao);// 执行代理类的方法userDaoProxy.learn();}
}

二、cglib提供的:针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以该类或方法最好不要声明成final,要想使用基于子类的动态代理:就必须得导入cglib的jar包。测试代码如下:

通过配置pom.xml导入cglib需要的相关架包

    <dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.2.4.RELEASE</version></dependency>

 1、创建CustomerDaoImpl类,未实现接口

package cglib;public class CustomerDaoImpl {public void learn(){System.out.println("开始学习,今天啥也没学会");}
}

2、创建代理类CglibProxy

package cglib;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CglibProxy implements MethodInterceptor{private Object object;// 被代理的目标对象public Object createProxy(Object object){this.object = object;//1.创建Cglib的核心类对象Enhancer enhancer = new Enhancer();//2. 设置代理目标enhancer.setSuperclass(object.getClass());//3.设置回调:类似于InvocationHandler对象enhancer.setCallback(this);return enhancer.create();}public Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {Object result = null;try {System.out.println("大宝子妈妈给你带了旺仔牛奶 ...");result = methodProxy.invoke(object, args);// 执行目标对象的方法System.out.println("小兔崽子你快欠揍了  ...");} catch (Exception e) {System.out.println(" 异常处理 ...");} finally {System.out.println(" 调用结束 ...");}return result;}
}

3、创建测试类及运行结果

package cglib;public class TestCglib {public static void main(String[] args) {CustomerDaoImpl testcglib = new CustomerDaoImpl();testcglib.learn();//未使用代理System.out.println("----------分割线----------");CglibProxy proxy = new CglibProxy();CustomerDaoImpl testcglib2 = (CustomerDaoImpl) proxy.createProxy(testcglib);testcglib2.learn();}
}

三、使用spring AOP代理实现:

1、创建项目,引入相关架包

在IDEA中创建一个名为spring02的Web项目,并将相关架包复制到lib目录,并发布到类路径下(具体操作方法在实验一中已经介绍,这里不详细说明,实验一地址:(29条消息) 实验一:Spriing IOC基本操作_老徐爱吃肉!的博客-CSDN博客)

在这里我们需要将本次使用的两个架包也复制到lib目录,并发布到类路径。

  • aopalliance.jar 是AOP联盟的API包,里面包含了针对面向切面的接口,通常Spring等其它具备动态织入功能的框架依赖此包,有需要的用户可以下载来使用。

aopalliance.jar下载地址https://sourceforge.net/projects/aopalliance/files/aopalliance/1.0/aopalliance.zip/download

  • spring-aop.jar 这个jar 文件包含在应用中使用Spring 的AOP 特性时所需的类和源码级元数据支持。 (该jar包在之前下载的spring-xxx-dist.zip中即可找到)

2、创建目标接口和实现类

在包中创建family接口和对应的实现类Boy。相关业务代码如下所示:

package xml;//定义接口
public interface family {public void learn();
}
package xml;public class Boy implements family {@Overridepublic void learn() {System.out.println("疯狂学习中");}
}

3、创建切面类

在com.springmvc.aop.xml.bean包中,创建MyAspect类实现MethodInterceptor接口,在实现类中重写invok()方法。参考代码如下所示:

package xml;import org.aspectj.lang.ProceedingJoinPoint;public class MyAspect {//前置增强,意思就是在业务逻辑方法调用前所植入的通用服务方法//一般这个方法用在权限的检查public void before() {System.out.println("妈妈买菜回来啦!一会就能干饭啦!");}//后置增强,一般就是在业务逻辑方法执行完毕之后所植入的通用方法//一般是用于资源的释放,如数据库连接对象的资源的释放public void after() {System.out.println("吃饱了就快学习吧");}//异常处理,因为一旦业务逻辑出现异常,那么就调用该方法//一般主要就是用于日志记录异常public void afterException(Throwable th) {System.out.println("干饭成功"+th.getMessage());}//返回值的增强,一般就是当执行一个业务逻辑方法的时候,有返回值的时候,那么就会植入该方法//一般可以用作日志记录public void afterReturn(Object result) {if(result==null) {System.out.println("吃饭中");}else {System.out.println("煤气罐没气了");}}//环绕增强,就是在业务逻辑方法执行期间所植入的方法。一般用以事务处理。//一般可以用作日志记录public Object around(ProceedingJoinPoint joinpoint) throws Throwable {System.out.println("妈妈要开始做饭了呦!");Object result = joinpoint.proceed();return result;}}

4、更改spring配置文件

在配置文件applicationContext.xml中,创建三个目标bean,一个切面bean和一个代理bean。关键代码如下所示:

<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><!-- 配置AOP --><!-- aop:config proxy-target-class="false"默认采用jdk的动态代理,只能针对接口的实现 --><!-- aop:config proxy-target-class="true"采用cglib的动态代理,可以直接针对普通的类来实现 --><aop:config><!-- 配置切面 --><aop:aspect id="myaspect" ref="myPointCut"><!-- 配置增强和表达式 --><!-- 配置切面表达式:表达式表示的是项目中哪些类或者哪些方法要被执行增强 --><aop:pointcut expression="execution(* xml.*.*(..))" id="mypointexpress"/><aop:before method="before" pointcut-ref="mypointexpress"/><aop:after method="after" pointcut-ref="mypointexpress"/><aop:around method="around" pointcut-ref="mypointexpress"/><!-- afterRunning增强 --><aop:after-returning method="afterReturn" returning="result" pointcut-ref="mypointexpress"/><!-- 配置after-throwing增强 --><aop:after-throwing method="afterException" throwing="th" pointcut-ref="mypointexpress"/></aop:aspect></aop:config><!-- 配置切面类的bean --><bean id="myPointCut" class="xml.MyAspect"></bean><!-- 配置业务逻辑类的bean对象 --><bean  id="boy" class="xml.Boy"></bean></beans>

5、编写测试类,进行测试

package xml;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Testdemo {@Testpublic void testUI() {//首先要获取spring的配置ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//动态代理只能针对接口实现family boy = ctx.getBean("boy",family.class);boy.learn();}
}

大概就是这么个意思,我也是新手,有不对的地方各位大佬请帮老弟指出来,我一定积极学习改正!

实验二 Spring AOP的使用相关推荐

  1. spring aop实现过程之二Spring AOP中拦截器链

    1.开始步骤--获取AopProxy主流程 ProxyCreatorSupport.java /*** Subclasses should call this to get a new AOP pro ...

  2. Spring AOP详细介绍

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Asp ...

  3. Spring AOP源码解析(二)—— AOP引入

    目录 配置类 AopAutoConfiguration AspectJAutoProxyingConfiguration ClassProxyingConfiguration @EnableAspec ...

  4. Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)

    AspectJ支持5种类型的通知注解: @Before:前置通知,在方法执行之前执行: @After:后置通知,在方法执行之后执行: @AfterRunning:返回通知,在方法返回结果之后执行(因此 ...

  5. Spring 学习笔记(二)Spring AOP

    前言 容器和AOP是Spring的两大核心.本文将来学习Spring AOP. AOP是什么? AOP在计算机科学领域还是相对年轻的概念,由Xerox PARC公司发明.Gregor Kiczales ...

  6. Spring AOP 源码初窥(二) 从注解开始

    版本 spring 5.0.8.BUILD-SNAPSHOT aspectjweaver 1.8.13 从注解开始 由于在本人实际应用中使用的是注解配置AOP,也更倾向于了解Spring AOP的整个 ...

  7. Spring 源码分析(三) —— AOP(二)Spring AOP 整体架构

    2019独角兽企业重金招聘Python工程师标准>>> Spring AOP 架构         先是生成代理对象,然后是拦截器的作用,最后是编织的具体实现.这是AOP实现的三个步 ...

  8. Spring中的AOP(二)——AOP基本概念和Spring对AOP的支持

    AOP的基本概念 AOP从运行的角度考虑程序的流程,提取业务处理过程的切面.AOP面向的是程序运行中的各个步骤,希望以更好的方式来组合业务逻辑的各个步骤.AOP框架并不与特定的代码耦合,AOP框架能处 ...

  9. 【Spring AOP】@Aspect结合案例详解(二): @Pointcut使用@within和within(已附源码)

    文章目录 前言 @within 完善打印日志案例 @within深入说明 within 匹配指定类 匹配指定包(package) 源码下载 总结 前言 在微服务流行的当下,在使用Spring Clou ...

最新文章

  1. c# typeof() 和 GetType()的区别
  2. Webkit 最新 Javascript 引擎领先 Chrome
  3. 技术宝典 | ToB 业务场景下自动化测试的实践及探索
  4. centos下载mysql_python数据分析之路——centos下载并配置mysql与navicat的使用
  5. keyboard dialog 仿微博表情键盘输入框
  6. 数据挖掘第三版课后习题
  7. 三菱plc c语言模块,FX5-80SSC-S 三菱PLC简易运动控制器模块
  8. Ps如何制作动态图片
  9. 飞桨领航团武汉长沙 | AI如何1秒记笔记,检测你的皮肤状态?
  10. 马未都说收藏:陶瓷篇(3、4、5)宋瓷-官窑-汝官哥钧定
  11. 使用python进行数据清洗常用的库_用于格式化和数据清理的便捷Python库
  12. 戴尔R230安装esxi
  13. 安卓开发必须会的技能!Android性能优化最佳实践,知乎上转疯了!
  14. 80C51单片机:4.中断、定时器
  15. LInux服务器的基本优化
  16. 为啥214被塞狗粮的单身汪,520还会被塞狗粮
  17. 前端模块化- ES Module 和 CommonJS 的使用
  18. vue中px 转 vh/vw
  19. Mysql主从复制之异步与半同步以及主从切换(实验)
  20. Flutter 生成 Icon 提示徽标 Widget

热门文章

  1. 用友T3-出纳通多个账户合并制单
  2. 线性代数 --- 如何用行向量和列向量对矩阵进行操作?
  3. 微型计算机转移指令,川大《微机原理与应用(1)1351》14秋在线作业1答案
  4. 【转载】门电路组成D触发器
  5. 【数字IC快速入门】linux基本操作
  6. linux 设备驱动(一)——字符设备驱动
  7. free与 available 之间区别
  8. Funcode桌球游戏源代码(可直接复制运行)
  9. 添加pdf打印机后给PDF添加背景
  10. leetcode2021年度刷题分类型总结(八)贪心 (python)