什么是AOP?

1.AOP概念介绍

  所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程。

   功能: 让关注点代码与业务代码分离!

关注点:

 重复代码就叫做关注点;

业务代码:

    核心业务的代码

业务代码与关注点代码分离,好处?

   --> 关注点代码写一次即可;

-->开发者只需要关注核心业务;

-->运行时期,执行核心业务代码时候动态植入关注点代码; 【代理】

如何分离?

过程式/对象式/代理模式分离

  AOP的好处是可以动态地添加和删除在切面上的逻辑而不影响原来的执行代码

切面,

关注点形成的类,就叫切面(类)!

面向切面编程,就是指 对很多功能都有的重复的代码抽取,再在运行的时候往业务方法上动态植入“切面类代码”。

切入点(拦截的作用)

执行目标对象方法,动态植入切面代码。

可以通过切入点表达式,指定拦截哪些类的哪些方法; 给指定的类在运行的时候植入切面类代码。

注解方式实现AOP编程

步骤:

1) 先引入aop相关jar文件           (aspectj  aop优秀组件)

spring-aop-3.2.5.RELEASE.jar   【spring3.2源码】

    aopalliance.jar                         【spring2.5源码/lib/aopalliance】

      aspectjweaver.jar                    【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】

    aspectjrt.jar                            【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】

注意: 用到spring2.5版本的jar文件,如果用jdk1.7可能会有问题。

需要升级aspectj组件,即使用aspectj-1.8.2版本中提供jar文件提供。

2) bean.xml中引入aop名称空间

3) 开启aop注解

4) 使用注解

@Aspect                                                              指定一个类为切面类

@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")  指定切入点表达式

@Before("pointCut_()")                                    前置通知: 目标方法之前执行

@After("pointCut_()")                                         后置通知:目标方法之后执行(始终执行)

@AfterReturning("pointCut_()")                         返回后通知: 执行方法结束前执行(异常不执行)

@AfterThrowing("pointCut_()")                            异常通知:  出现异常时候执行

@Around("pointCut_()")                                      环绕通知: 环绕目标方法执行

代码示例:

1、bean.xml中引入aop名称空间

2、 开启aop注解

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:aop="http://www.springframework.org/schema/aop"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd
  12. http://www.springframework.org/schema/aop
  13. http://www.springframework.org/schema/aop/spring-aop.xsd">
  14.  
  15. <!-- 使用注解时要开启注解扫描 要扫描的包 -->
  16. <context:component-scan base-package="cn.itcast.e_aop_anno"></context:component-scan>
  17.  
  18. <!-- 开启aop注解方式 -->
  19. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  20. </beans>

3、指定切面类

  1. @Component //加入IOC容器
  2. @Aspect // 指定当前类为切面类
  3. public class Aop {
  4.  
  5. // 指定切入点表达式: 拦截哪些方法; 即为哪些类生成代理对象
      //解释@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
  1.   //@Pointcut("execution(* 切入点表达式固定写法, cn.itcast.e_aop_anno表示包.类名(可以用*表示包下所有的类).方法名(可以用*表示类下所有的方法)(..)表示参数可以用..
  1. @Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
  2. public void pointCut_(){
  3. }

  4.   //@Before("execution(* cn.itcast.e_aop_anno.*.*(..))")每个方法需要写相同的引用,所以将相同的部分抽取到一个空的方法中pointCut_(),
  5. // 前置通知 : 在执行目标方法之前执行
  6. @Before("pointCut_()")
  7. public void begin(){
  8. System.out.println("开始事务/异常");
  9. }
  10.  
  11. // 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
  12. @After("pointCut_()")
  13. public void after(){
  14. System.out.println("提交事务/关闭");
  15. }
  16.  
  17. // 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
  18. @AfterReturning("pointCut_()")
  19. public void afterReturning() {
  20. System.out.println("afterReturning()");
  21. }
  22.  
  23. // 异常通知: 当目标方法执行异常时候执行此关注点代码
  24. @AfterThrowing("pointCut_()")
  25. public void afterThrowing(){
  26. System.out.println("afterThrowing()");
  27. }
  28.  
  29. // 环绕通知:环绕目标方式执行
  30. @Around("pointCut_()")
  31. public void around(ProceedingJoinPoint pjp) throws Throwable{
  32. System.out.println("环绕前....");
  33. pjp.proceed(); // 执行目标方法
  34. System.out.println("环绕后....");
  35. }
  36.  
  37. }

接口

  1. // 接口
  2. public interface IUserDao {
  3. void save();
  4. }

4、目标对象类一:实现接口

  1. /**
  2. * 目标对象
  3. */
  4. @Component // 加入容器
  5. public class UserDao implements IUserDao{
  6.  
  7. @Override
  8. public void save() {
  9. System.out.println("-----核心业务:保存!!!------");
  10. }
  11. }

目标对象类二:没有实现接口

  1. /**
  2. * 目标对象*/
  3. @Component // 加入容器
  4. @Scope("prototype")
  5. public class OrderDao{
  6.  
  7. public void save() {
  8. System.out.println("-----核心业务:保存!!!------");
  9. }
  10. }

测试类

  1. public class App {
  2.  
  3. ApplicationContext ac =
  4. new ClassPathXmlApplicationContext("cn/itcast/e_aop_anno/bean.xml");
  5.  
  6. // 目标对象有实现接口,spring会自动选择“JDK代理”
  7. @Test
  8. public void testApp() {
  9. IUserDao userDao = (IUserDao) ac.getBean("userDao");
  10. System.out.println(userDao.getClass());//$Proxy001
  11. userDao.save();
  12. }
  13.  
  14. // 目标对象没有实现接口, spring会用“cglib代理”
  15. @Test
  16. public void testCglib() {
  17. OrderDao orderDao = (OrderDao) ac.getBean("orderDao");
  18. System.out.println(orderDao.getClass());
  19. orderDao.save();
  20. }

输出结果:

    开始事务/异常

    -----核心业务:保存!!!------

    提交事务/关闭


XML方式实现AOP编程

Xml实现aop编程:

1) 引入jar文件  【aop 相关jar, 4个】

2) 引入aop名称空间

3)aop 配置

* 配置切面类 (重复执行代码形成的类)

* aop配置

拦截哪些方法 / 拦截到方法后应用通知代码

代码示例:

bean.xml配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:aop="http://www.springframework.org/schema/aop"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd
  12. http://www.springframework.org/schema/aop
  13. http://www.springframework.org/schema/aop/spring-aop.xsd">
  14.  
  15. <!-- dao 实例 在这里配置后就不用在类中使用注解 -->
  16. <bean id="userDao" class="cn.itcast.f_aop_xml.UserDao"></bean>
  17. <bean id="orderDao" class="cn.itcast.f_aop_xml.OrderDao"></bean>
  18.  
  19. <!-- 切面类 -->
  20. <bean id="aop" class="cn.itcast.f_aop_xml.Aop"></bean>
  21.  
  22. <!-- Aop配置 -->
  23. <aop:config>
  24. <!-- 定义一个切入点表达式: 拦截哪些方法 -->
  25. <aop:pointcut expression="execution(* cn.itcast.f_aop_xml.*.*(..))" id="pt"/>
  26. <!-- 切面 -->
  27. <aop:aspect ref="aop">
  28. <!-- 环绕通知 -->
  29. <aop:around method="around" pointcut-ref="pt"/>
  30. <!-- 前置通知: 在目标方法调用前执行 -->
  31. <aop:before method="begin" pointcut-ref="pt"/>
  32. <!-- 后置通知: -->
  33. <aop:after method="after" pointcut-ref="pt"/>
  34. <!-- 返回后通知 -->
  35. <aop:after-returning method="afterReturning" pointcut-ref="pt"/>
  36. <!-- 异常通知 -->
  37. <aop:after-throwing method="afterThrowing" pointcut-ref="pt"/>
  38.  
  39. </aop:aspect>
  40. </aop:config>
  41. </beans>

全部使用xml配置后,类中注解全部去掉,代码同上

Spring的AOP面向切面编程的更多相关文章

  1. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  2. Spring 08: AOP面向切面编程 + 手写AOP框架

    核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...

  3. Spring框架 AOP面向切面编程(转)

    一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...

  4. spring:AOP面向切面编程02

    参考: https://blog.csdn.net/jeffleo/article/details/54136904 一.AOP的核心概念AOP(Aspect Oriented Programming ...

  5. Spring注解 - AOP 面向切面编程

    基本概念: AOP:Aspect Oriented Programming,即面向切面编程 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式 前置通知(@Before):在目标 ...

  6. Spring框架——AOP面向切面编程

    简介 AOP练习 使用动态代理解决问题 Spring AOP 用AspectJ注解声明切面 前置后置通知 利用方法签名编写AspectJ切入点表达式 指定切面的优先级 基于XML的配置声明切面 Spr ...

  7. Spring之AOP(面向切面编程)_入门Demo

    AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可 ...

  8. 【spring源码学习】spring的AOP面向切面编程的实现解析

    一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口  => ...

  9. 详解Spring框架AOP(面向切面编程)

    最近在学习AOP,之前一直很不明白,什么是AOP?为什么要使用AOP,它有什么作用?学完之后有一点小小的感触和自己的理解,所以在这里呢就跟大家一起分享一下 AOP(Aspect-Oriented Pr ...

随机推荐

  1. linux用户与组管理

    普通用户的管理 用户管理的基本任务包括添加新用户.删除用户.修改用户属性以及对现有用户的访问参数进行设置.与密切 相关的文件包含/etc/passwd./etc/shadow以及/home目录下的文件 ...

  2. Android-NDK编译

    (2013-12-19  21:48:21 其实一切还是先看看官网的好,乱百度浪费时间.... http://developer.android.com/tools/sdk/ndk/index.htm ...

  3. Eclipse: Android Device Chooser - Unknown Target

    公司最近所有的项目都使用到了Android开发手机(或PDA)应用.所需要的Android开发技术并不是非常复杂,因为我们的底层方法全部使用WebServcie写好了,做Android开发的人员只需要 ...

  4. Linux彻底删除mysql5.6

    查看安装的mysql组件 rpm -qa | grep -i mysql mysql57-community-release-el6-8.noarch mysql-community-common-5 ...

  5. bootstrap页面布局

    首先,我们必须明确,在这四种角色登录网站,看到页面是不同,这里不仅涉及到后端的权限控制,还涉及到前端页面的布局,区分好这些角色看的东西哪些是相同的,哪些又是不同的呢,这个必须在这里想明白,所以要做好页 ...

  6. VMware Workstation 虚拟机纯 Linux 终端如何安装 VMware Tools ?

    VMware Workstation 虚拟机纯 Linux 终端如何安装 VMware Tools ? 1.首先在虚拟机设置里面设置一个共享文件夹 2.在虚拟机菜单栏中选择 VMware Tools ...

  7. 使用QtConcurrent编写多线程程序(也可以阻塞)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Amnes1a/article/details/66470751Qt在其QtConcurrent命名空 ...

  8. Android系统移植与调试之------->增加一个双击物理按键打开和关闭闪光灯并将闪光灯状态同步到下拉菜单中

    最近有一个客户有这样的需求: 1.在[设置]--->[无障碍]中添加一个开关按钮. 如果打开开关的话,双击某个物理按键的时候,打开闪光灯,再双击该物理按键的时候,关闭闪光灯. 如果关闭开关的话, ...

  9. locust基本使用

    # coding:utf-8 from locust import HttpLocust,TaskSet,task class BlogDemo(TaskSet): '''用户行为:打开我的博客首页d ...

  10. mui 视频播放

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...