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 ...
随机推荐
- Java-技术专区-如何监控Java线程池的状态
线程池介绍 什么是线程池.线程池核心类.线程池工作流程.线程池分类.拒绝策略.及如何提交与关闭线程池等. 但在实际开发过程中,在线程池使用过程中可能会遇到各方面的故障,如线程池阻塞,无法提交新任务等. ...
- ubuntu16.04安装LNMP(ubuntu+Nginx+mysql+PHP7.0)
系统环境: Ubuntu 16.04.2 LTS nginx version: nginx/1.10.3 (Ubuntu) PHP 7.0.22-0ubuntu0.16.04.1 mysql Ver ...
- shell条件测试语句
- go语言从例子开始之Example4.常量
Go 支持字符.字符串.布尔和数值 常量 . package main import "fmt" import "math" const 用于声明一个常量. c ...
- 网络编程NIO-异步
异步I/O是没有阻塞地读写数据的方法.通常在代码进行read调用时,代码会阻塞直至可供读取的数据.同样,write调用将会阻塞直至数据能够写入. 1.selector是一个对象,可以注册到很多个cha ...
- webpack第一节(4)
每次修改了代码都需要重新手动打包,这样很麻烦,不符合webpack的初衷,我们查看webpack帮助看看有没有可以自动运行的方法 输入 webpack -help 可以发现有个 --watch方法 它 ...
- Vue学习笔记【32】——Vue路由(watch、computed和methods之间的对比)
computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算.主要当作属性来使用: methods方法表示一个具体的操作,主要书写业务逻辑: watch一个对象,键是需要观察的表达式,值是 ...
- JavaScript设计模式小抄集(持续更新)
前言 本文旨在记录JavaScript中常用的设计模式代码片段,简要说明使用场景,不过于追究细节.在设计模式开篇之前,还是先要搞清楚JavaScript中关于面向对象的基础知识,可以先看看JavaSc ...
- 旋转屏幕导致Activity重建问题的解决办法
Android开发文档上专门有一小节解释这个问题.简单来说,Activity是负责与用户交互的最主要机制,任何"设置"(Configuration)的改变都可能对Activity的 ...
- 【MySQL】mysql查询强制大小写及替换字段
强制大小写 select * from test where name like BINARY '%Adc%' mysql替换字段 update test set name= REPLACE (nam ...