1. 什么是AOP?

2. Spring底层的AOP实现原理

2.1. AOP应用场景

2.2. Spring动态代理

2.2.1. JDK动态代理: 只能对实现了接口的类产生代理。

2.2.2. CGLIB动态代理: 对没有实现接口的类产生代理。CGLIB(Code Generation Library)是一个开源的, 强大的, 高性能, 高质量的Code生成类库。Spring引入了它。

3. AOP简介

3.1. AOP思想最早是由AOP联盟组织提出的。Spring是使用这种思想的最好的框架。

3.2. AspectJ是一个面向切面的框架, 它扩展了Java语言。

3.3. Spring早期的AOP是自己实现的, 但是十分繁琐。后来Spring引入了AspectJ进行AOP开发。

4. AOP术语

5. Spring中通知类型

5.1. 前置通知: 在目标方法执行之前进行操作。

5.2. 后置通知: 在目标方法执行之后进行操作。

5.3. 环绕通知: 在目标方法执行之前和之后进行操作。

5.4. 异常抛出通知: 在程序出现异常的时候进行操作。

5.5. 最终通知: 无论代理是否有异常, 总会执行。

6. 切入点表达式语法

6.1. 基于execution的函数完成的。

6.2. [访问修饰符] 返回值类型 包名.类名.方法名(参数), 访问修饰符可以省略不写。

6.3. public void com.lywgames.dao.impl.UserDaoImpl.insert(..), 参数使用.., 表示任意参数。

6.4. * com.lywgames.dao.impl.UserDaoImpl.insert(..), 返回值使用*, 表示任意返回值类型。

6.5. * com..UserDaoImpl.insert(..), 包路径可以使用..做省略, 但是必须有开头。

6.6. * com.lywgames.dao.impl.*.*(..), 该包下的所有类的所有方法。

7. 引入aop的约束

8. 切入点配置

9. 通知配置

10. JDK动态代理例子

10.1. 新建一个名为JdkProxy的Java项目

10.2. 创建UserDao.java接口

package com.lywgames.dao;public interface UserDao {void insert();void select();void update();void delete();
}

10.3. 创建UserDao.java接口的实现类UserDaoImpl.java

package com.lywgames.dao.impl;import com.lywgames.dao.UserDao;public class UserDaoImpl implements UserDao {@Overridepublic void insert() {System.out.println("插入User对象。");}@Overridepublic void select() {System.out.println("查询User对象。");}@Overridepublic void update() {System.out.println("更新User对象。");}@Overridepublic void delete() {System.out.println("删除User对象。");}}

10.4. 创建JDKProxy.java代理类

package com.lywgames.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.lywgames.dao.UserDao;public class JDKProxy implements InvocationHandler{private UserDao userDao;public JDKProxy(UserDao userDao) {this.userDao = userDao;}public UserDao createProxy() {return (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if("select".equals(method.getName())) {System.out.println("查询User对象前, 对其进行校验。");return method.invoke(userDao, args);}return method.invoke(userDao, args);}}

10.5. 创建Test.java测试类

package com.lywgames;import com.lywgames.dao.UserDao;
import com.lywgames.dao.impl.UserDaoImpl;
import com.lywgames.proxy.JDKProxy;public class Test {public static void main(String[] args) {UserDao userDao = new UserDaoImpl();JDKProxy jdkProxy = new JDKProxy(userDao);UserDao proxy = jdkProxy.createProxy();proxy.insert();proxy.select();proxy.update();proxy.delete();}
}

10.6. 运行项目

11. CGLIB动态代理例子

11.1. 新建一个名为CglibProxy的Java项目, 拷入spring-core.java, 她有CGLIB代码

11.2. 创建UserDaoImpl.java类

package com.lywgames.dao.impl;public class UserDaoImpl {public void insert() {System.out.println("插入User对象。");}public void select() {System.out.println("查询User对象。");}public void update() {System.out.println("更新User对象。");}public void delete() {System.out.println("删除User对象。");}}

11.3. 创建CglibProxy.java代理类

package com.lywgames.proxy;import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.lywgames.dao.impl.UserDaoImpl;public class CglibProxy implements MethodInterceptor {private UserDaoImpl userDaoImpl;public CglibProxy(UserDaoImpl userDaoImpl) {this.userDaoImpl = userDaoImpl;}// 使用cglib产生代理public UserDaoImpl createProxy() {// 创建cglib的核心类Enhancer enhancer = new Enhancer();// 设置父类enhancer.setSuperclass(userDaoImpl.getClass());// 设置回调enhancer.setCallback(this);// 返回增强对象return (UserDaoImpl)enhancer.create();}@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {if("insert".equals(method.getName())) {System.out.println("插入User对象前, 对其进行校验。");return methodProxy.invokeSuper(proxy, args);}return methodProxy.invokeSuper(proxy, args);}}

11.4. 创建Test.java测试类

package com.lywgames;import com.lywgames.dao.impl.UserDaoImpl;
import com.lywgames.proxy.CglibProxy;public class Test {public static void main(String[] args) {UserDaoImpl userDaoImpl = new UserDaoImpl();CglibProxy cglibProxy = new CglibProxy(userDaoImpl);UserDaoImpl proxy = cglibProxy.createProxy();proxy.insert();proxy.select();proxy.update();proxy.delete();}
}

11.5. 运行项目

12. AOP使用XML配置例子

12.1. 新建一个名为AOPXml的Java项目

12.2. 创建UserDao.java接口

package com.lywgames.dao;public interface UserDao {public void insert();public void select();public void update();public int delete();
}

12.3. 创建UserDao.java接口的实现类UserDaoImpl.java

package com.lywgames.dao.impl;import com.lywgames.dao.UserDao;public class UserDaoImpl implements UserDao {public void insert() {System.out.println("插入数据");}public void select() {System.out.println("查询数据");}public void update() {System.out.println("更新数据");throw new RuntimeException();}public int delete() {System.out.println("删除数据");return 1;}}

12.4. 创建AspectJAop.java切面类

package com.lywgames.aop;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;public class AspectJAop {public void beforeInsertCheck(JoinPoint jp) {System.out.println("检测插入数据, " + jp);}public void afterDelete(int result) {System.out.println("删除后返回值: " + result);}public Object arround(ProceedingJoinPoint joinPoint) {try {System.out.println("查询前鼓鼓掌。");Object obj = joinPoint.proceed();System.out.println("查询后鼓鼓掌。");return obj;} catch (Throwable e) {e.printStackTrace();}return null;}public void updateException(Throwable ex) {System.out.println("更新发生了异常:" + ex.toString());}public void myFinally() {System.out.println("更新方法发生了异常, 最终通知一样会执行完成。");}
}

12.5. 创建AopAction.java测试类

package com.lywgames.action;import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.lywgames.dao.UserDao;public class AopAction {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao = context.getBean(UserDao.class);userDao.insert();userDao.delete();userDao.select();userDao.update();context.close();}
}

12.6. 在src目录下添加applicationContext.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.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userDao" class="com.lywgames.dao.impl.UserDaoImpl"></bean><bean id="aspectJAop" class="com.lywgames.aop.AspectJAop"></bean><!-- 通过aop的配置完成对目标类产生代理 --><aop:config><!-- 表达式配置哪些类的哪些方法需要进行增强 --><aop:pointcut expression="execution(* com..UserDaoImpl.insert(..))" id="pointinsert" /><aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.delete(..))" id="pointdelete"/><aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.select(..))" id="pointselect"/><aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.update(..))" id="pointupdate"/> <!-- 配置切面 --><aop:aspect ref="aspectJAop"><!-- 引用切面类 --><!-- 前置通知 --><aop:before method="beforeInsertCheck" pointcut-ref="pointinsert" /><!-- 后置通知 --><aop:after-returning method="afterDelete" pointcut-ref="pointdelete" returning="result"/><!-- 环绕通知 --><aop:around method="arround" pointcut-ref="pointselect"/><!-- 异常通知 --><aop:after-throwing method="updateException" pointcut-ref="pointupdate" throwing="ex" /> <!-- 最终通知 --><aop:after method="myFinally" pointcut-ref="pointupdate"/></aop:aspect></aop:config></beans>

12.7. 运行项目

010_AOPXml方式开发相关推荐

  1. php接口调用实例源代码,小蚂蚁学习APP接口开发(7)—— APP接口实例——读取缓存方式开发APP接口的代码案例...

    从数据库中直接读取数据,虽然时效性很强,但是对数据库造成很大压力,尤其是在高访问量的情况下.这时候可以通过缓存,来有效的缓解了这一压力,虽然时效性有些不足,但是服务器的抗压能力却达到了很大的提高. 读 ...

  2. Xfire方式开发和解析webservice

    Xfire方式开发和解析webservice 具体的开发webservice步骤: 1. 新建项目 2. 导入相关xfire架包 主要xfire-1.2.6下xfire-all-1.2.6.jar架包 ...

  3. WT32-SC01是ESP32驱动3.5彩屏开发板方案适合用arduino方式开发吗?因为需要彩屏和电容触摸的驱动的

    ESP32驱动3.5寸彩屏开发板方案因为带有彩屏和电容触摸的驱动,能否用arduino方式开发,这是很多熟悉arduino开发的技术人员关心的问题. 目前启明云端推出的http://esp32.8ms ...

  4. QtCreator与catkin命令两种方式开发ROS程序(图示加代码)

    QtCreator与catkin命令两种方式开发ROS程序(图示加代码) 一.Qt Creator安装及开发ROS 1.安装Qt Creator 2.使用Qt Creator开发ROS 1.创建工作空 ...

  5. 搭建Spring Boot2.X集成Hibernate5项目,并集成传统SSH老项目的安全认证组件,以Spring Boot方式开发项目并集成到老系统

    搭建Spring Boot2.X集成Hibernate5项目,并集成传统SSH老项目的安全认证组件,以Spring Boot方式开发项目并集成到老系统 场景 可行性分析 搭建Spring Boot集成 ...

  6. JAX-WS方式开发和部署webservice应用

    JAX-WS方式开发和部署webservice应用 1.创建webservice工程 2.书写服务端代码 3.配置文件 4.启动服务,查看wsdl 5.客户端调用测试 其他 需要源码的可以去我的资源里 ...

  7. Spark远程调试+页面监控--用最熟悉的方式开发Spark应用

    ​ 大家好. 我是楼兰,持续分享最纯粹的技术内容. ​ 大数据技术已经大行其道,但是很多人对大数据组件依然会觉得很陌生,很不顺手.对大部分人来说,环境部署.API使用其实问题都不大,技术人员最不欠缺的 ...

  8. Arduino方式开发ESP32笔记:使用Preferences保存数据

    本文大部分参考使用Arduino开发ESP32(18):使用Preferences保存数据 引出 在其他单片机上我们可以使用单片机自带Flash来保存一些数据,在ESP32上也可以这样,在ESP32的 ...

  9. android studio ndk-builld方式开发

    之前都是在Ubuntu开发,项目也是老的,自然也就顺理成章的用eclipse做各种android的开发.最近想在android studio 切换下,有点不习惯.android studio 为ndk ...

最新文章

  1. python导入excel数据-python + Excel数据读取(更新)
  2. CVPR 2021 | 基于跨任务场景结构知识迁移的单张深度图像超分辨率方法
  3. Thymeleaf 语法快速入门
  4. 中国35位“大国工匠”榜单出炉!西工大、西电合计占半壁江山!清华仅1人!...
  5. 调试opencv程序显示应用程序无法正常启动,0xc000007b
  6. WebLogic Classloader分析工具
  7. 在VM2008R2中使用模板快速创建虚拟机之一准备篇
  8. Android学习之布局管理器嵌套
  9. 推荐Python互动艺术在线编辑器(腾讯扣叮)
  10. 2019CSP-S初赛知识点汇总
  11. [USACO5.1] Musical Themes
  12. dedecms注入漏洞 5.3 5.5
  13. REST another WebService???
  14. 李彦宏宣布百度架构调整:智能云事业部升级
  15. Atitit mysql存储过程编写指南 1. 定义变量 1 1.1. 变量名以@开头用户变量 会话变量 1 1.2. 以declare关键字声明 存储过程变量 2 1.3. @是用户自定义变量,
  16. paip.判断字符是否中文与以及判读是否是汉字uapi python java php
  17. Oracle 11g数据库基础教程(第2版)-课后习题-第十三章
  18. 工程矩阵理论 Hermite 矩阵
  19. imageAI基本使用
  20. 获取GeoScene Pro 90天免费试用版

热门文章

  1. multiple problems have occured
  2. 奇妙的Base64编码
  3. 2010后的经济增长点再研究
  4. VMware vSAN6.7 设计和优化 vSAN 主机--
  5. 在CentOS上用yum安装redis
  6. QDU第一届程序设计大赛——E到I题解法(非官方题解)
  7. ASP.NET Core macOS 环境配置 - ASP.NET Core 基础教程 - 简单教程,简单编程
  8. 2017-2018-1 20155201 实验五 通讯协议设计
  9. Visual Studio 2017 最新全量离线下载方法[有惊喜]
  10. 将spark默认日志log4j替换为logback