AOP是针对面向对象编程的一种补充,有时使用面向对象不能很好完成一些额外的功能业务时,可以采用AOP来进行补充。

AOP术语:

  1. 切面(Aspect)

    切面是用于编写切面逻辑的一个类,这个类很类似于JDK动态代理中的回调处理器或者cglib中的方法拦截器,主要就是将需要增强目标对象的功能代码编写在这个类中,而这些功能增强的代码就是切面逻辑。

  2. 切入点(Pointcut)

    切入点类似一个切入的坐标,目的就是要找到目标对象的哪些方法。

    通常切入点都是以一种表达式的形式来描述

  3. 通知/增强(Advice)

    通知就是切面中具体的增强逻辑,总共分为五种:

    1)前置通知(在目标方法调用之前执行)

    2)后置通知(在目标方法正确返回之后执行)

    3)环绕通知(在目标方法调用前后执行)

    4)异常通知(当目标方法抛出异常时执行,并且不会执行后置通知)

    5)最终通知(不管目标方法有无异常都会执行)

  4. 连接点(Joinpoint)

    目标对象的方法就称之为连接点,一个切入点可以对应目标对象的的多个连接点。

  5. 代理(Proxy)

    在运行时动态创建的对象,称之为代理对象,负责调用目标对象的方法,并执行增强功能

  6. 目标(Target)

    被代理的对象就是目标对象

  7. 织入(Weaver)

    将切面中的通知应用到目标对象上并且产生代理的过程称之为织入。

    因此通常描述为“将通知织入到具体的目标”。


项目结构:

代码示例:

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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 装备UserServiceImpl -->
<bean id="userService" class="edu.nf.ch11.service.impl.UserServiceImpl"/> <!-- 装配自定义的切面-->
<bean id="userServiceAspect" class="edu.nf.ch11.service.aspect.UserServiceAspect"/> <!-- 配置AOP, proxy-target-class用于设置是否强制使用cglib进行动态代理
true表示强制使用,false则表示spring会根据目标对象有无实现接口来决定
使用jdk动态代理还是cglib代理。默认值就是false-->
<aop:config>
<!-- 配置切入点,id属性给切入点定义一个唯一标识,expression用于编写切入点表达式-->
<!-- execution表达式的使用:切入范围是在方法级别-->
<!-- 表达式语法[访问修饰符] 返回值类型 [完整类名].方法名(参数)-->
<!-- *号表示通配所有,方法的参数可以使用".."来代表任意个数和类型的参数-->
<aop:pointcut id="myCut" expression="execution(* edu.nf.ch11.service.*.*(..))"/> <!-- within表达式的使用:切入范围是在类级别-->
<!--<aop:pointcut id="myCut" expression="within(edu.nf.ch11.service.impl.*)"/>--> <!-- 引用上面装配的切面类的id -->
<aop:aspect ref="userServiceAspect">
<!-- 配置具体的通知方法,method指定通知的方法名
pointcut-ref引用上面定的切入点的id,也可以通过pointcut来编写相应的切入点表达式 -->
<!-- 前置通知 -->
<aop:before method="before" pointcut-ref="myCut"/>
<!-- 环绕通知-->
<aop:around method="around" pointcut-ref="myCut"/>
<!-- 后置通知,returning指定后置通知的参数名,用于获取目标方法的返回值-->
<aop:after-returning method="afterReturn" pointcut-ref="myCut" returning="returnVal"/>
<!-- 异常通知,如果要获取目标方法抛出的异常对象,需要指定throwing属性,value对应异常通知的参数名-->
<aop:after-throwing method="throwAdvice" pointcut-ref="myCut" throwing="e"/>
<!-- 最终通知-->
<aop:after method="after" pointcut-ref="myCut"/>
</aop:aspect> </aop:config> </beans>

切面(增强)类:

package edu.nf.ch11.service.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature; import javax.xml.crypto.dsig.SignatureMethod; /**
* @author wangl
* @date 2018/10/23
* 编写一个UserService的切面
* 在切面中编写的方法都称之为通知或者是增强
* 在AOP当中,通知有五种类型
* 1. 前置通知
* 2. 后置通知
* 3. 环绕通知
* 4. 最终通知
* 5. 异常通知
* 在一个切面中,任何一种类型的通知都可以定义多个,当有多个通知存在的时候
* 就会形成一个通知栈
*/
public class UserServiceAspect { /**
* 前置通知
* 在执行目标方法之前执行,拦截目标方法的参数
* 可以通过JoinPoint获得目标方法的参数信息
*/
public void before(JoinPoint joinPoint){
System.out.println("前置通知...");
//通过连接点获得目标对象
//joinPoint.getTarget();
//获取目标方法的参数信息
Object[] params = joinPoint.getArgs();
for (Object param : params) {
System.out.println(param);
}
} /**
* 后置通知
* 在目标方法执行完并且return之后执行
*/
public void afterReturn(String returnVal){
System.out.println("后置通知..."+returnVal);
} /**
* 环绕通知
* @param pjp 连接点处理器,由它负责调用目标对象的具体方法
*
*/
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知前...");
//调用目标对象的方法
Object returnVal = pjp.proceed();
//获取目标方法的参数
System.out.println(pjp.getArgs()[0]);
//通过MethodSignature获取连接点方法信息
MethodSignature ms = (MethodSignature)pjp.getSignature();
//获取正在调用的目标方法
System.out.println(ms.getMethod().getName());
//获取目标方法的返回类型
System.out.println(ms.getReturnType());
System.out.println("环绕通知后...");
return returnVal;
} /**
* 异常通知
* @param e 获取目标方法抛出的异常对象
*/
public void throwAdvice(Throwable e){
System.out.println("异常通知..."+e.getMessage());
} /**
* 最终通知
*/
public void after(){
System.out.println("最终通知...");
}
}

UserService接口:

package edu.nf.ch11.service;

/**
* @author wangl
* @date 2018/10/23
*/
public interface UserService { /**
* 添加用户
*/
void addUser(); /**
* 删除用户
* @param uid
*/
void deleteUser(String uid); /**
* 查询用户
* @param uid
* @return
*/
String getUserNameById(String uid);
}

UserServiceImpl实现类:

package edu.nf.ch11.service.impl;

import edu.nf.ch11.service.UserService;

/**
* @author wangl
* @date 2018/10/23
* 目标对象(被代理的对象)
* Spring的AOP中需要代理的所有目标对象都应该归纳在ioc容器中管理
*/
public class UserServiceImpl implements UserService { @Override
public void addUser() {
System.out.println("保存用户信息");
} @Override
public void deleteUser(String uid) {
System.out.println("删除用户,ID:" + uid);
} @Override
public String getUserNameById(String uid) {
System.out.println("根据ID查询用户名");
//System.out.println(10/0);
return "user1";
}
}

程序测试类:

package edu.nf.ch11.test;

import edu.nf.ch11.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author wangl
* @date 2018/10/23
*/
public class UserServiceAspectTest { @Test
public void testAddUser(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//这里从容器中获取的对象是一个代理对象
UserService service = context.getBean("userService", UserService.class);
//service.addUser();
//System.out.println("----------------------");
//service.deleteUser("10001");
//System.out.println("----------------------");
service.getUserNameById("10001");
}
}

运行结果

spring-AOP(面向切面编程)-xml方式配置的更多相关文章

  1. 详细解读 Spring AOP 面向切面编程(二)

    本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...

  2. 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~

    简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...

  3. spring AOP面向切面编程学习笔记

    一.面向切面编程简介: 在调用某些类的方法时,要在方法执行前或后进行预处理或后处理:预处理或后处理的操作被封装在另一个类中.如图中,UserService类在执行addUser()或updateUse ...

  4. 【Spring系列】Spring AOP面向切面编程

    前言 接上一篇文章,在上午中使用了切面做防重复控制,本文着重介绍切面AOP. 在开发中,有一些功能行为是通用的,比如.日志管理.安全和事务,它们有一个共同点就是分布于应用中的多处,这种功能被称为横切关 ...

  5. 从源码入手,一文带你读懂Spring AOP面向切面编程

    之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...

  6. Spring AOP面向切面编程详解

    前言 AOP即面向切面编程,是一种编程思想,OOP的延续.在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等.在阅读本文前希望您已经对Spring有一定的了解 注:在能对代码进行添 ...

  7. 详细解读 Spring AOP 面向切面编程(一)

    又是一个周末, 今天我要和大家分享的是 AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之. ...

  8. Spring Aop面向切面编程&&自动注入

    1.面向切面编程 在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面的过程叫做面向切面编程 2.常用概念 原有功能:切点,pointcut 前置通知:在切点之前执行的功能,befor ...

  9. Spring AOP 面向切面编程入门

    什么是AOP AOP(Aspect Oriented Programming),即面向切面编程.众所周知,OOP(面向对象编程)通过的是继承.封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的 ...

随机推荐

  1. final,finally,finalize有什么区别?String, StringBuffer, StringBuilder有什么区别?Exception和Error有什么区别?

    继上篇JVM学习之后,后面将分三期深入介绍剩余JAVA基础面试题,每期3题. 题目一.final,finally,finalize有什么区别? /*请尊重作者劳动成果,转载请标明原文链接:*/ /* ...

  2. MySQL 5.6的一个bug引发的故障

    突然收到告警,提示mysql宕机了,该服务器是从库.于是尝试登录服务器看看能否登录,发现可以登录,查看mysql进程也存在,尝试登录提示 ERROR (HY000): Too many connect ...

  3. 详谈js防抖和节流

    本文由小芭乐发表 0. 引入 首先举一个例子: 模拟在输入框输入后做ajax查询请求,没有加入防抖和节流的效果,这里附上完整可执行代码: <!DOCTYPE html> <html ...

  4. 【Apache Kafka】Kafka学习笔记

    0x00 基本信息 1.Kafka架构图 2.环境信息 服务器IP:xx.xx.xx.xx 操作系统:CentOS7.2_x64 Kafka版本:kafka_2.12-1.1.0 Zookeeper版 ...

  5. shiro源码篇 - shiro的filter,你值得拥有

    前言 开心一刻 已经报废了一年多的电脑,今天特么突然开机了,吓老子一跳,只见电脑管家缓缓地出来了,本次开机一共用时一年零六个月,打败了全国0%的电脑,电脑管家已经对您的电脑失去信心,然后它把自己卸载了 ...

  6. jdk 8 的内存参数修改

    jdk内存实际是jvm内存,jvm有一个运行时数据区,其实就是对这一部分的大小分配.运行时数据区通常包括这几个部分:程序计数器(Program Counter Register).Java栈(VM S ...

  7. ARM 汇编指令 DCD

    简介 DCD:数据定义( Data Definition )伪指令 一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化. 语法格式: 标号 DCD(或 DCDU) 表达式 DCD(或 ...

  8. WebSocket+Java 私聊、群聊实例

    前言 之前写毕业设计的时候就想加上聊天系统,当时已经用ajax长轮询实现了一个(还不懂什么是轮询机制的,猛戳这里:https://www.cnblogs.com/hoojo/p/longPolling ...

  9. vue 路由 及 跳转传递参数的总结

    博客地址:https://ainyi.com/4 vue-router vue-router 是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用.vue的单页面应用是基 ...

  10. php常用函数搜集

    搜集了几个php常用函数方法....相信项目中肯定会用到吧... <?php /** * @param $arr * @param $key_name * @return array * 将数据 ...