04-Spring中的AOP编程之基于xml开发
AOP编程
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
学习AOP之后,可以在不修改源码的情况下,进行源码的增强业务,进行权限的校验,日志记录,性能监控,事务控制等。
Spring底层的AOP原理
动态代理(静态代理)
- JDK动态代理: 面向接口的,只能对实现了接口的类产生代理
- Cglib动态代理(类似于JavaSsit第三方代理技术):对没有实现接口的类产生代理对象(生成子类对象)
类实现了接口,Spring就用JDK动态代理,没有实现接口的,用Cglib动态代理,Spring底层可以自动切换
Spring的AOP开发入门(1)(基于XML开发)
1. 引入基本开发包和AOP开发相关的包

第一个aop联盟
第二个aspectj的依赖
第三个AOP核心包
第四个Spring与aspects整合的包
2. 引入xml配置约束文件
写切面的约束:aspect.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">
<!--切面编程配置-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="p1" expression="execution(* com.yd.service.impl.UserServiceImpl.add(..))"/>
<!--配置切面类-->
<aop:aspect ref="myAspect">
<aop:before method="log" pointcut-ref="p1"></aop:before>
</aop:aspect>
</aop:config>
</beans>
写spring扫描类文件,管理相关类的对象:spring.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
<context:component-scan base-package="com.yd.service"></context:component-scan>
<context:component-scan base-package="com.yd.aspect"></context:component-scan>
</beans>
3. 编写原本的代码(切入点)

UserService:
public interface UserService {
//添加用户方法
public void add();
}
接口的实现类UserServiceImpl:
- 使用@Service将该类交由spring容器管理
@Service
public class UserServiceImpl implements UserService {
@Override
public void add(){
System.out.println("添加用户信息...");
}
}
4. 编写增强类(通知)

- 使用@Component将该类交由spring容器管理
@Component
public class MyAspect {
public void log(){
System.out.println("添加日志");
}
}
5. 运行测试代码
public class Demo {
@Test
public void run(){
//引入配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext( "spring.xml","aspect.xml");
//从spring容器中获取对象
UserService userService = (UserService)ac.getBean("userServiceImpl");
//执行对象方法
userService.add();
}
}
运行结果:

Spring的AOP开发入门(2)(基于XML开发)

UserService:
public interface UserService {
public void add();
public void delete();
public String deleteReturn();
public void deleteAround();
public void update(String uname,int pwd);
public String updateReturn(String uname,int pwd);
public void selectException();
public void selectFin();
}
实现类UserServiceImpl:
@Service
public class UserServiceImpl implements UserService {
@Override
public void add(){
System.out.println("添加用户信息...");
}
@Override
public void delete() {
System.out.println("删除用户信息...");
}
@Override
public String deleteReturn() {
System.out.println("删除用户,有返回值...");
return "123";
}
@Override
public void deleteAround(){
System.out.println("删除信息deleteAround...");
}
@Override
public void update(String uname,int pwd) {
System.out.println("uname:"+uname+" pwd:"+pwd);
}
@Override
public String updateReturn(String uname,int pwd) {
System.out.println("uname:"+uname+" pwd:"+pwd);
return uname;
}
@Override
public void selectException() {
System.out.println("select异常。。。");
System.out.println(1/0);
System.out.println("select2。。。");
}
@Override
public void selectFin() {
System.out.println("select无异常。。。");
}
}
增强类MyAspect:
@Component
public class MyAspect {
public void check(){
System.out.println("----之前校验身份");
}
public void back(){
System.out.println("----之后增强");
}
/**
* 接收原方法返回值的后置增强方法
* @param obj 切入点的返回值
*/
public void backReturn(Object obj){
System.out.println("后置接收切入点返回值:"+obj);
}
/**
* 环绕增强
* @param point 连接点
* @throws Throwable
*/
public void around(ProceedingJoinPoint point) throws Throwable {
System.out.println("----之前增强");
//执行切入点的方法
point.proceed();
System.out.println("----之后增强");
}
/**
* 环绕增强,接收切入点的传入的参数
* @param point
* @throws Throwable
*/
public void aroundParam(ProceedingJoinPoint point)throws Throwable{
System.out.println("---之前增强");
//获取切入点的参数
Object[] args = point.getArgs();
point.proceed();
System.out.println("---之后增强 切入点参数1:"+args[0]+" 参数2:"+args[1]);
}
/**
* 环绕增强,接收切入点的传入的参数,切接收返回
* @param point
* @throws Throwable
*/
public void aroundReturn(ProceedingJoinPoint point)throws Throwable{
System.out.println("---之前增强");
//获取切入点的参数
Object[] args = point.getArgs();
String str = (String)point.proceed();
System.out.println("---之后增强 切入点参数1:"+args[0]+" 参数2:"+args[1]+" 返回值:"+str);
}
/**
* 切入点有异常
* @param e 异常
*/
public void afterCatch(Exception e){
System.out.println(e.getMessage());
System.out.println("---捕获异常");
}
public void finallyDo(){
System.out.println("finally,总会执行...");
}
}
AOP配置文件:
<?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">
<!--切面编程配置-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="p1" expression="execution(* com.yd.service.impl.UserServiceImpl.add(..))"/>
<aop:pointcut id="p2" expression="execution(* com.yd.service.impl.UserServiceImpl.delete(..))"/>
<aop:pointcut id="p3" expression="execution(* com.yd.service.impl.UserServiceImpl.deleteReturn(..))"/>
<aop:pointcut id="p4" expression="execution(* com.yd.service.impl.UserServiceImpl.deleteAround(..))"/>
<aop:pointcut id="p5" expression="execution(* com.yd.service.impl.UserServiceImpl.update(..))"/>
<aop:pointcut id="p6" expression="execution(* com.yd.service.impl.UserServiceImpl.updateReturn(..))"/>
<aop:pointcut id="p7" expression="execution(* com.yd.service.impl.UserServiceImpl.selectException(..))"/>
<aop:pointcut id="p8" expression="execution(* com.yd.service.impl.UserServiceImpl.selectFin(..))"/>
<!--配置切面类-->
<aop:aspect ref="myAspect">
<!-- 之前增强-->
<aop:before method="check" pointcut-ref="p1"></aop:before>
<!-- 之后增强-->
<aop:after-returning method="back" pointcut-ref="p2"></aop:after-returning>
<!-- 之后增强接收切入点返回值 obj:增强方法接收返回值的参数,必须与方法中参数名一致-->
<aop:after-returning method="backReturn" pointcut-ref="p3" returning="obj"></aop:after-returning>
<!-- 环绕增强-->
<aop:around method="around" pointcut-ref="p4"></aop:around>
<!-- 环绕增强,获取切入点传入的参数信息-->
<aop:around method="aroundParam" pointcut-ref="p5"></aop:around>
<!-- 环绕增强,获取切入点传入的参数信息,且有返回-->
<aop:around method="aroundReturn" pointcut-ref="p6"></aop:around>
<!-- 最终通知,有无异常都会执行,相当于finally-->
<aop:after method="finallyDo" pointcut-ref="p7"></aop:after>
<!-- 切入点有异常,后置增强捕获 throwing="e"异常参数,必须与方法中一致-->
<aop:after-throwing method="afterCatch" pointcut-ref="p7" throwing="e"></aop:after-throwing>
<aop:after method="finallyDo" pointcut-ref="p8"></aop:after>
</aop:aspect>
</aop:config>
</beans>
测试类:
public class Demo {
@Test
public void run(){
ApplicationContext ac = new ClassPathXmlApplicationContext( "spring.xml","aspect.xml");
UserService userService = (UserService)ac.getBean("userServiceImpl");
//userService.add();
//userService.delete();
//userService.deleteReturn();
//userService.deleteAround();
//userService.update("张三",1234);
//userService.updateReturn("李四",121);
//userService.selectException();
userService.selectFin();
}
- 注意:最终通知after和后置异常通知after-throwing的顺序不同,打印结果顺序不同
方式一:

运行结果

方式二:

运行结果:

切入点表达式语法
基于execution的函数完成的
语法
- execution([访问修饰符] 方法返回值 包名.类名.方法名(参数))
com.spring.service.UserServiceImpl.add(..) 一般情况最好将方法名写完整
com.spring.service.UserServiceImpl.*(..) 开发中用的最多的是这种,对当前类下所有的方法做增强处理(场景:事务处理)
com.spring.service.impl.save(..)
com.spring.service.impl.*(..) 表示: com.spring.service.impl类下所有方法被增强
* *.*service.impl.add(..)没有包可以用*代替
* com.spring..(..)表示com.spring包下所有的类,所有方法都被增强
04-Spring中的AOP编程之基于xml开发的更多相关文章
- Spring中Bean的配置:基于XML文件的方式
Bean的配置一共有两种方式:一种是基于XML文件的方式,另一种是基于注解的方式.本文主要介绍基于XML文件的方式 <bean id="helloWorld" class=& ...
- Spring中的AOP注解方式和XML方式
应掌握内容:1. AOP的全名2. AOP的实现原理[静态代理和动态代理]3. 注解方式的配置4. 通知类型 A. 每种通知的特点和使用方式 B. 获取各种数据,方便日后操作5. 执行表 ...
- Spring AOP——Spring 中面向切面编程
前面两篇文章记录了 Spring IOC 的相关知识,本文记录 Spring 中的另一特性 AOP 相关知识. 部分参考资料: <Spring实战(第4版)> <轻量级 JavaEE ...
- Spring中的AOP 专题
Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...
- Spring入门3.AOP编程
Spring入门3.AOP编程 代码下载: 链接: http://pan.baidu.com/s/11mYEO 密码: x7wa 前言: 前面学习的知识是Spring在Java项目中的IoC或DJ,这 ...
- JavaWeb_(Spring框架)认识Spring中的aop
1.aop思想介绍(面向切面编程):将纵向重复代码,横向抽取解决,简称:横切 2.Spring中的aop:无需我们自己写动态代理的代码,spring可以将容器中管理对象生成动态代理对象,前提是我们对他 ...
- (五)Spring 中的 aop
目录 文章目录 AOP概念 AOP原理 AOP术语 **`Spring`** 中的 **`aop`** 的操作 使用 `AspectJ` 实现 `aop` 的两种方式 AOP概念 浅理解 aop :面 ...
- Spring中的AOP
什么是AOP? (以下内容来自百度百科) 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种 ...
- Spring中关于AOP的实践之概念
一.什么是AOP AOP:也称作面向切面编程 在分享几个概念执行我想先举个栗子(可能例子举得并不是特别恰当): 1.假如路人A走在大街上,被一群坏人绑架了: 2.警察叔叔接到报警迅速展开行动:收集情报 ...
- Spring学习笔记(四)—— Spring中的AOP
一.AOP概述 AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.O ...
随机推荐
- Vue全局方法配置
在Vue项目开发中,肯定会有这样一个场景:在不同的组件页面用到同样的方法,比如格式化时间,文件下载,对象深拷贝,返回数据类型,复制文本等等.这时候我们就需要把常用函数抽离出来,提供给全局使用.那如何才 ...
- Java基础——(综合练习)生成5位验证码
package com.zhao.test; import java.util.Random; public class Test16 { /*需求: 定义方法实现随机产生一个5位的验证码 验证码格式 ...
- Python面向对象编程——一些类定义(杂)
一.abstractmethod 子类必须全部实现重写父类的abstractmethod方法 非abstractmethod方法可以不实现重写 带abstractmethod方法的类不能实例化 fro ...
- 非线性优化-SLAM14CP6
在前声明下面有一部分直接引用高翔老师SLAM14讲中的内容.因为我实在是看不懂.临时放在这里.以后有用到再做详细研究. 在SLAM14讲的CP2中第一次引入运动方程以及观测方程来描述物体带着传感器在空 ...
- ethcat开发记录 一
一.方案 1.移植开源方案SOEM 2.专用芯片 二.SOEM移植 (一)硬件 stm32f407,168M PHY:LAN8720A (ii) Points to note 1, the PHY a ...
- ios MJRefresh 上拉死循环刷新问题+git 图片
网上各种办法都试了,只有这种解决方法解决了我的问题,记录一下 通过延迟 1s后,再来请求接口 - (void)viewDidLoad { [super viewDidLoad]; // Do any ...
- oracle 锁用户和解锁。
1 批量锁用户--数据库迁移后不允许在连接了 SELECT 'alter user '||username||' account lock;' from dba_users WHERE usernam ...
- SQL server——基础篇之数据完整性
定义:保证数据库中的数据在逻辑上的一致性.正确性和可靠性. 作用:防止无效数据或错误数据进入数据库 数据完整性包括:实体完整性.域完整性和参照完整性 实体完整性 规定表的每一行记录在表中是唯一的 实体 ...
- SQL Server 解析Json(单层/多层)
一,单层Json数据取出 1.取出取出@JsonData字符串中的 __type,DocNo,OrderPriceTC,Organization_Code 字段 DECLARE @JsonData ...
- UVA10404
由题意可知,这题和巴什博弈没什么关系了 相似题目:AtCoder Beginner Contest 278 F - Shiritori 预备知识:DP,博弈论的必胜态和必败态 问题的关键是确定\(f_ ...