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 ...
随机推荐
- (读书笔记)基于CMMI的软件工程及实训指导------第一章软件工程基础
第一章------软件工程基础 1.软件工程基本原理 (1)按照软件生命周期的阶段划分制订计划,严格依据计划进行管理 (2)坚持进行阶段评审 (3)实行严格的产品控制 (4)采用现代程序设计技术 (5 ...
- Nginx+UWSGI+supervisor
Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检 ...
- 启动JAVA服务
# -*- coding: utf-8 -*- import re import sys from subprocess import Popen, PIPE import os import tim ...
- redis之redisObject对象
redisObject对象 无论什么数据类型,redis都是以key-value形式保存,并且所有的key都是字符串redis每存储一条数据,都会生成一个redisObject对象,通过redisOb ...
- 在Windows系统上安装和配置Jenkins自动发布
一.安装jenkins的流程转载于: https://www.jianshu.com/p/de9c4f5ae7fa 二.在window中执行批处理文件bat或者powershell可以成功,但是Jen ...
- js判断变量数据类型typeof、instanceof、Object.prototype.toString.call()、 constructor
JavaScript有4种方法判断变量的类型,分别是typeof.instanceof.Object.prototype.toString.call()(对象原型链判断方法). constructor ...
- oracle建表和sqlserver建表
oracle declare num number;begin select count(1) into num from user_all_tables where Upper(Table_Name ...
- phpmyadmin scripts/setup.php 反序列化漏洞(WooYun-2016-199433)(Kali)
phpmyadmin 2.x版本中存在一处反序列化漏洞,通过该漏洞,攻击者可以读取任意文件或执行任意代码. 通过vulhub靶场进行复现操作 1.首先搭建靶场环境(采用Kali) cd vulhu ...
- 【NumPy】Python将数组中低于一定百分比的值替换
情景举例 现有一个一维数组(或二维进行遍历)存放着很多,找到低于中位数20%的值并将小于该值的数全部替换为该值. 涉及方法 np.median(data, axis=0)用于计算数组中元素的中位数(中 ...
- elementUI el-tree报错 Cannot read property ‘setCheckedKeys’ of undefined"
给树节点赋值时,执行下面代码会报错,原因是:DOM元素未加载完成. 以下为错误写法. handleRowClick(row) { this.$refs.tree.setCheckedKeys(ids) ...