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 ...
随机推荐
- 用户积分排行榜功能-Redis实现
一.排行榜功能简介 排行榜功能是一个很普遍的需求.使用 Redis 中有序集合(SortedSet)的特性来实现排行榜是又好又快的选择. 一般排行榜都是有实效性的,比如交通数据流中的路口/路段的车流量 ...
- Linux下创建动态库与使用
参考文章:dll和so文件区别与构成:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html 动态库路径配置- /etc/ld.so. ...
- php 字符转成数字
1.第一种转换方式:在要转换的变量之前加上用括号括起来的目标类型,如 (int):(bool):(float):(string):(array):(object) 2.第二种转换方式:使用3个具体类型 ...
- 配置框架spring和SpringDataJpa整合----员工是爹
<!-- 1.dataSource 配置数据库连接池--> <bean id="dataSource" class="com.mchange.v2.c3 ...
- hdu 4705 Y (树形dp)
Description Input 4 1 2 1 3 1 4 题目的意思是给你一棵树,让你找到所有不在一条路径上的三个点的情况个数.乍一看正向处理比较麻烦,我们从反方向考虑,如果是取在一条路径上的3 ...
- 获取FileSystem
/** * 根据配置文件获取HDFS操作对象 * 有两种方法: * 1.使用conf直接从本地获取配置文件创建HDFS对象 * 2.多用于本地没有hadoop系统,但是可以远程访问.使用给定的URI和 ...
- IP地址的定义和划分
IP地址分类: IP地址根据首首字节开始位可以分为5大类: 分类 首字节开始位 首字节数字范围 ...
- 理解同步/异步/阻塞/非阻塞IO区别
5种IO模型 1.阻塞式I/O模型 阻塞I/O(blocking I/O)模型,进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误才返回.进程从调用recvfr ...
- Linux下Mysql安装与常见问题解决方案
1.Mysql安装 环境: Mysql版本: 开始安装: 首先检查环境有没有老版本mysql,有的话先卸载干净,具体百度. 接着先获取mysql的安装包:wget https://dev.mysql. ...
- PHP【Laravel】delayer基于redis的实现订单超时改变状态
实现这个功能前你需要知道以下,不然可能会比较吃力:1.服务器的计划任务,shell脚本,或者你有宝塔自带的计划任务会方便很多.2.有所了解Redis.3.会写PHP业务逻辑. 好了进入在正题,这里使用 ...