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 ...
随机推荐
- pat题目整理
Pat最终题目整理(菜鸟级别) 一:几个函数 ①Reverse()函数: stoi将字符串类型转为int型 :to_string关键字 头文件:#include<algorithm>; # ...
- window 画工业图软件
1.autoCAD 2.visio 3.CorelDraw 4.DrawIO
- 逆向学习物联网-网关ESP8266-05课程小结
1. 移花接木 本章利用自己设计的网关代替体验系统中的网关,开启了分模块设计系统的设计模式. 2.透明传输 终端传输来的数据,以MQTT协议透明传输到云及其他订阅者,简化终端系统的设计. 3. 利用状 ...
- Flink配置详解及实践
#jobManager的IP地址jobmanager.rpc.address: localhost #JobManager的端口号jobmanager.rpc.port: 6123 # JobMana ...
- 用Python中的hashlib实现md5和sha加密
文章目录 一.用 pandas 读取 Excel 数据 二.加密库 hashlib 三. pandas中的 map() 方法 四.数据加密工具 本文分享知识: pandas读取Excel数据 read ...
- RabbitMQ消息堆积问题?
原因: 有时可能因为消费者自身代码问题,导致没办法正常消费消息,那么就会导致消息队列中会堆积大量的消息: 或因为同一时间来了非常多的消息,消费者没办法及时消费,导致消息队列中堆积了大量消息. 解决办法 ...
- Java中String,JSON对象,java实体类(Bean)之间的相互转换
FastJson对于json格式字符串的解析主要用到了一下三个类: (1)JSON:fastJson的解析器,用于JSON格式字符串与JSON对象及javaBean之间的转换. (2)JSONObje ...
- pdfjs-dist 后端返回文件前端实现预览pdf
pdfjs-dist锁定版本号2.2.228,别的都不太好使,各种各样的报错 不锁定的时候升高版本出现pdf预览不了 引用的时候 import pdfjsLib from 'pdfjs-dist/bu ...
- [CQOI2014]通配符匹配 题解
第一眼:什么鬼东西ヾ(。`Д´。) 第二眼:显然,这道题要分段处理 类似[TJOI2018]碱基序列\ (建议做一做也是Hash+DP)\ 那你怎么第一眼没看出来 Hash处理+DP==AC 直接上代 ...
- 使用TLS/SSL传输层安全机制实现web项目的通信安全
自己的web项目在内网ip访问时,浏览器会提示不安全 原因就是因为没有证书,而传输层的TLS/SSL协议,会告诉我们本地客户端的浏览器,我现在访问的web项目的ip地址可能存在安全风险 要解决这个通信 ...