Spring中AOP的基于xml开发和配置
pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.mepu</groupId>
<artifactId>day04_Spring_Aop</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver
解析切入点表达式
-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
</dependencies>
</project>
service层:
package cn.mepu.service.imp;
import cn.mepu.service.IAccountService;
/**
* 账户业务层实现类
* @author shkstart
* @create 2019-11-09 15:23
*/
public class AccountServiceImp implements IAccountService {
@Override
public void saveAccount() {
System.out.println("保存");
}
@Override
public void updateAccount(int i) {
System.out.println("更新"+i);
}
@Override
public int deleteAccount() {
System.out.println("删除");
return 0;
}
}
日志层:
package cn.mepu.utils;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 记录日志,提供公共代码
* @author shkstart
* @create 2019-11-09 15:25
*/
public class logger {
/**
* 前置日志
*/
public void beforePrintLog(){
System.out.println(" logger中前置开始记录日志" );
}
/**
* 后置日志
*/
public void afterreturningPrintLog(){
System.out.println(" logger中后置开始记录日志" );
}
/**
* 异常日志
*/
public void afterThrowingPrintLog(){
System.out.println(" logger中异常开始记录日志" );
}
/**
* 最终日志
*/
public void afterPrintLog(){
System.out.println(" logger中最终开始记录日志" );
}
/**
* 环绕通知
* 问题:
* 当配置环绕执行后,切入点没有执行,通知方法执行了
* 分析:
* 动态代理中的环绕通知有明确的切入点方法调用,而本次没有
* 解决:
* Spring框架提供一个接口,ProceedingJoinPoint 该接口有一个proceed()方法,此方法相对于明确调用切入点方法
* 该接口可以作为环绕通知的方法参数,在程序运行时,spring框架会提供该接口的实现类供我们使用
* Spring的环绕通知:
* spring框架为我们提供的一种可以在代码中可以手动控制增强方法何时执行的方式
*/
public Object aroundPringLog(ProceedingJoinPoint pjp){
Object reValue = null;
try {
Object[] args = pjp.getArgs();//得到方法所需的参数
//前置通知
System.out.println("logger中环绕通知开始记录日志前置" );
pjp.proceed(args);//明确调用切入点方法
//后置通知
System.out.println("logger中环绕通知开始记录日志后置" );
return reValue;
} catch (Throwable throwable) {
//异常通知
System.out.println("logger中环绕通知开始记录日志异常" );
throw new RuntimeException(throwable);
}finally {
//最终通知
System.out.println("logger中环绕通知开始记录日志最终" );
}
}
}
配置文件层:
<?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">
<!--配置spring的Ioc把service对象配置进来-->
<bean id="accountService" class="cn.mepu.service.imp.AccountServiceImp"></bean>
<!-- Spring中基于XML的aop配置步骤
1.把通知bean交给spring管理
2.使用aop:config标签表明AOP的配置
3.使用aop:acpect标签表明配置切面
id给切片提供唯一标识
ref:通知类bean的id
4.在aop:acpect标签内部使用对应的标签来配置通知的类型
我们现在的示例是让printLog方法在切入点方法执行之前执行:前置通知
aop:before表示配置前置通知
method:用于指定logger类中哪个方法是前置通知
pointcut:指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强
切入点表达式的写法:
关键字:execution(表达式)
表达式:访问修饰符 返回值 包名.包名.方法名(参数列表)
标准写法:
public void cn.mepu.service.imp.AccountServiceImp.saveAccount()
访问修饰符可以省略
void cn.mepu.service.imp.AccountServiceImp.saveAccount()
返回值可以使用通配符表示任意返回值
* cn.mepu.service.imp.AccountServiceImp.saveAccount()
包名可以使用通配符,表示任意包,但是有几个包就需要写几个*
* *.*.*.*.AccountServiceImp.saveAccount()
包名可以使用..包括当前包或子包
* *..AccountServiceImp.saveAccount()
类名和方法名可以使用*实现统配
* *..*.*()
全统配写法:括号中..表示有无参数都可以
* *..*.*(..)
实际开发中切入点表达式通常写为:
切到业务层实现类下的所有方法
* cn.mepu.service.imp.*.*(..)
-->
<!-- 配置logger类-->
<bean id="logger" class="cn.mepu.utils.logger"></bean>
<!-- 配置AOP-->
<aop:config>
<!--配置切入点表达式标签 id指定唯一标识 expression表达式内容
此标签写在切面aop:aspect标签内部只能当前切面可以使用
可以写在aop:aspect外面,此时变成所有切面可用
改造上边的-->
<aop:pointcut id="pt1" expression="execution( * *..*.*(..))"/>
<!--为了环绕通知把四个通知注上 配置切面-->
<aop:aspect id="logAdvice" ref="logger">
<!-- 配置前置通知,并且建立通知方法和切入点方法的关联
<aop:before method="beforePrintLog" pointcut="execution( * *..*.*(..))"></aop:before>
<aop:before method="beforePrintLog" pointcut-ref="pt1"></aop:before>-->
<!-- 配置后置通知,并且建立通知方法和切入点方法的关联
<aop:after-returning method="afterreturningPrintLog" pointcut-ref="pt1"></aop:after-returning>-->
<!-- 配置异常通知,并且建立通知方法和切入点方法的关联
<aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"></aop:after-throwing>-->
<!-- 配置最终通知,并且建立通知方法和切入点方法的关联
<aop:after method="afterPrintLog" pointcut-ref="pt1"></aop:after>-->
<!-- 配置环绕通知 说明在Log类中-->
<aop:around method="aroundPringLog" pointcut-ref="pt1"></aop:around>
</aop:aspect>
</aop:config>
</beans>
测试层:
package cn.mepu.Test;
import cn.mepu.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试Aop
* @author shkstart
* @create 2019-11-09 15:59
*/
public class AopTest {
public static void main(String[] args) {
//1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("Bean.xml");
//2.获取对象
IAccountService as = (IAccountService) ac.getBean("accountService");
//3.执行方法
as.saveAccount();
}
}
Spring中AOP的基于xml开发和配置的更多相关文章
- 面向切面编程AOP:基于XML文件的配置
除了使用AspectJ注解声明切面,Spring也支持在bean的配置文件中声明切面,这种声明是通过aop scheme中的XML元素完成的. 首先建立一个类: package com.sevenhu ...
- 【学习】Spring 的 AOP :基于Annotation 的“零配置”方式
转自:http://www.cnblogs.com/jbelial/archive/2012/07/20/2539123.html AOP(Aspect Orient Programming ) , ...
- Spring使用AspectJ开发AOP:基于XML
基于XML的声明式 基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面.切入点及声明通知,而所有的切面和通知都必须定义在 <aop:config> 元素中. 下面通过案例 ...
- Spring 框架的概述以及Spring中基于XML的IOC配置
Spring 框架的概述以及Spring中基于XML的IOC配置 一.简介 Spring的两大核心:IOC(DI)与AOP,IOC是反转控制,DI依赖注入 特点:轻量级.依赖注入.面向切面编程.容器. ...
- 十四 Spring的AOP的基于AspectJ的注解开发
Spring的AOP的基于AspectJ的注解开发 创建项目,引入jar包 编写目标类.切面类 配置目标类.切面类 在注解文件里开启AOP的开发 <?xml version="1.0& ...
- 基于Spring的可扩展Schema进行开发自定义配置标签支持
一.背景 最近和朋友一起想开发一个类似alibaba dubbo的功能的工具,其中就用到了基于Spring的可扩展Schema进行开发自定义配置标签支持,通过上网查资料自己写了一个demo.今天在这里 ...
- Spring中AOP原理,源码学习笔记
一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...
- Spring中AOP简介与切面编程的使用
Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...
- 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)
一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...
随机推荐
- HDU 1029Ignatius and the Princess IV
Ignatius and the Princess IV Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32767 K ( ...
- expdp和impdp
前言 一句话 expdp和impdp,只能在本地服务器运行 使用前 1.创建逻辑目录,该命令不会在操作系统创建真正的目录,最好以system等管理员创建. create directory dpd ...
- 三、Redis的配置文件和多数据库用途
1.使用文件 # 使用配置文件启动 redis-server ./redis.conf # 带配置文件启动 且指定某几个配置 配置名称前加 -- redis-server ./redis.conf - ...
- 解密native代码的内存使用
前言 无论是从资源使用的角度,还是从发现内存泄漏问题的角度来看,在性能测试或者系统的稳定性测试中,内存的使用情况是一个很重要的监控点.为保证项目的质量前移,输入法内核测试小组的同学分配到了一个新的任务 ...
- ajax中json格式数据如何朝后端发送数据
- Ceph的正确玩法之Ceph纠删码理论与实践
http://blog.itpub.net/31545808/viewspace-2637083/ 注意空格,有的命令少空格 随着云计算业务的快速发展,国内外云计算企业的专利之争也愈发激烈.在云计算这 ...
- Python基础教程(008)--第一个Python程序
前言: 学会第一个Python程序 了解Python2和Python3的区别 内容 执行Python程序的三种方式 解释器--Python.Python3 交互式-- ipthon 集成开发环境--P ...
- VS2013 MFC基于对话框编程
前言一直利用Qt库做Ui设计,但针对于一些MFC项目,掌握一些必要的MFC开发技巧还是很有必要的.这篇博客里就将自己所学的一些MFC浅显知识记录一下,方便今后的学习.博客里只记录关键步骤. 一.新建M ...
- 埋在MySQL数据库应用中的17个关键问题
出处:https://blog.csdn.net/weixin_42882439 MySQL的使用非常普遍,跟MySQL有关的话题也非常多,如性能优化.高可用性.强一致性.安全.备份.集群.横向扩展. ...
- springboot controller传参,对象映射
Post请求,对象映射时,在参数 加 @RequestBody: 传入对象内字段的json才能映射 {"legendData": [100,90,80,70,60,50,40,30 ...