Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较
本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同。
相关引入包等Spring AOP编程准备,请参考小编的其他博文,这里不再赘述。
案例要求:
写一个简单的实现四则运算的计算器。
加入AOP功能:日志功能;检测参数中是否有负数的功能。
废话不多说了,直接上代码:
(一)基于XML配置:
定义了一个接口类:
package com.edu.aop;
public interface ArithmeticCalculator {
int add(int i,int j);
int sub(int i,int j);
int mul(int i,int j);
int div(int i,int j);
}
实现类:
package com.edu.aop;
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
@Override
public int add(int i, int j) {
return i+j;
}
@Override
public int sub(int i, int j) {
return i-j;
}
@Override
public int mul(int i, int j) {
return i*j;
}
@Override
public int div(int i, int j) {
return i/j;
}
}
日志切片类:
package com.edu.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
public class LoggingAspect {
/**
* 日志切面类
*/
public void beforeMethod(JoinPoint joinPoint){
//获取方法名
String methodName=joinPoint.getSignature().getName();
//获取方法实参值列表
Object[] args=joinPoint.getArgs();
System.out.println("The method "+methodName+" begin with "+Arrays.asList(args));
}
public void afterMethod(JoinPoint joinPoint){
String methodName=joinPoint.getSignature().getName();
System.out.println("The method "+methodName+" ends");
}
}
检测参数中是否有负数的切片类:
package com.edu.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
public class ValidationAspect {
public void validationArgs(JoinPoint joinPoint){
String methodName=joinPoint.getSignature().getName();
Object[] args=joinPoint.getArgs();
System.out.println("待验证参数:"+Arrays.asList(args));
if(args!=null&&args.length>0){
for(int i=0;i<args.length;++i){
if(((Integer)args[i]).intValue()<0){
System.out.println("警告:方法"+methodName+"()第"+(i+1)+"个参数为负数:"+args[i]);
}
}
}
}
}
xml配置文件applicationContext.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"> <!-- 配置bean -->
<bean id="arithmetic" class="com.edu.aop.ArithmeticCalculatorImpl"></bean> <!-- 分别将切面类声明配置成一个bean -->
<bean id="logging" class="com.edu.aop.LoggingAspect"></bean>
<bean id="validation" class="com.edu.aop.ValidationAspect"></bean> <aop:config>
<!-- 配置日志切片类 -->
<aop:aspect ref="logging" order="2">
<!-- 配置前置通知 及前置通知的切入点-->
<aop:before method="beforeMethod" pointcut="execution(* com.edu.aop.ArithmeticCalculatorImpl.*(..))"></aop:before>
<!-- 配置后置通知及后置通知的切入点 -->
<aop:after method="afterMethod" pointcut="execution(* com.edu.aop.ArithmeticCalculatorImpl.*(..))"></aop:after>
</aop:aspect> <!-- 配置检测参数切片类 -->
<aop:aspect ref="validation" order="1">
<!-- 配置前置通知 及前置通知的切入点-->
<aop:before method="validationArgs" pointcut="execution(* com.edu.aop.ArithmeticCalculatorImpl.*(..))"></aop:before>
</aop:aspect>
</aop:config>
</beans>
主方法检测类:
package com.edu.aop; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
ArithmeticCalculator arithmetic=(ArithmeticCalculator)act.getBean("arithmetic");
int result=arithmetic.add(10, 20);
System.out.println("result:"+result);
result=arithmetic.div(-36, 4);
System.out.println("result:"+result);
} }
运行结果:

(二)基于AspectJ注解配置的AOP编程:
直接上代码:
接口类定义同上。
xml配置文件applicationContext.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"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 自动扫描的包,实现对注解Bean的管理 -->
<context:component-scan base-package="com.edu.aop"></context:component-scan>
<!-- 使Aspect的注解起作用,从而实现:自动为匹配的类生成代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
接口实现类:
package com.edu.aop; import org.springframework.stereotype.Component; //@Component 注解Bean,并设定其名称为arithmetic
@Component("arithmetic")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override
public int add(int i, int j) {
return i+j;
} @Override
public int sub(int i, int j) {
return i-j;
} @Override
public int mul(int i, int j) {
return i*j;
} @Override
public int div(int i, int j) {
return i/j;
} }
日志切片类:
package com.edu.aop; import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; //注释声明切面,切面的名称为默认名称(loggingAspect)(即类名首字母小写)
@Order(2) //注释切面的优先级别,数字越小,级别越高
@Aspect //@Aspect 注解声明该Bean是个切面
@Component //@Component 注解Bean,默认名称为loggingAspect
public class LoggingAspect {
/**
* 日志切面类
*/
//注释“前置通知”及其切入点
@Before("execution(public int com.edu.aop.ArithmeticCalculator.add(int,int))")
public void beforeMethod(JoinPoint joinPoint){
//获取方法名
String methodName=joinPoint.getSignature().getName();
//获取方法实参值列表
Object[] args=joinPoint.getArgs();
System.out.println("The method "+methodName+" begin with "+Arrays.asList(args));
} //注解“后置通知”及其切入点
@After("execution(* com.edu.aop.ArithmeticCalculator.*(..))")
public void afterMethod(JoinPoint joinPoint){
String methodName=joinPoint.getSignature().getName();
System.out.println("The method "+methodName+" ends");
}
}
检测参数中是否有负数的切片类:
package com.edu.aop; import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; //注释声明切面,切面的名称为默认名称(loggingAspect)(即类名首字母小写)
@Order(1) //注解切面的优先级别,数字越小,级别越高
@Aspect //注解为一个切面
@Component //注解为一个Bean组件,默认名称为validationAspect
public class ValidationAspect { //注解为前置通知,并注解其切入点表达式
@Before("execution(* com.edu.aop.ArithmeticCalculator.*(..))")
public void validationArgs(JoinPoint joinPoint){
String methodName=joinPoint.getSignature().getName();
Object[] args=joinPoint.getArgs();
System.out.println("待验证参数:"+Arrays.asList(args));
if(args!=null&&args.length>0){
for(int i=0;i<args.length;++i){
if(((Integer)args[i]).intValue()<0){
System.out.println("警告:方法"+methodName+"()第"+(i+1)+"个参数为负数:"+args[i]);
}
}
}
}
}
主方法检测类同上。
运行结果:

由以上案例的两个版本,可以看到两种AOP编程方式在设计思想和设计过程基本一致,只不过,“基于XML的AOP编程”是将配置Bean、切面、通知等操作放在了配置文件中。而“基于AspectJ的AOP编程”则是将这些配置信息放在了源码中,只在配置文件中配置了“AspectJ的注解支持”(即空的<aop:aspectj-autoproxy>元素)和自动扫描的包的支持。
Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较的更多相关文章
- Spring学习之旅(七)--SpringMVC视图
在之前的实例中我们只是在 Controller 中返回了 home 字符类型的值,而没有直接生成可以在浏览器中直接渲染的 HTML,这是因为 SpringMVC 将请求处理的逻辑和视图渲染的实现进行了 ...
- Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探
由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...
- spring基于xml的声明式事务控制配置步骤
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Spring学习笔记(七)模拟实际开发过程的调用过程XML版-Setter方式注入
模拟实际开发过程的调用过程XML版-Setter方式注入 源码获取github [TOC] 1.项目结构 2.jar包跟上个一样 3.重写set方法 UserServiceImpl.java 1234 ...
- Spring学习之旅(六)Spring AOP工作原理初探
AOP(Aspect-Oriented Programming,面向切面编程)是Spring提供的关键技术之一. AOP基于IoC,是对OOP(Object-Oriented Programming ...
- Spring学习之旅(五)--AOP
什么是 AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是 OOP(Object-Oriented Programing,面向对象编程)的补充和完善. OO ...
- spring 基于XML的申明式AspectJ通知的执行顺序
spring 基于XML的申明式AspectJ通知的执行顺序 关于各种通知的执行顺序,结论:与配置文件中的申明顺序有关 1. XML文件配置说明 图片来源:<Java EE企业级应用开发教程&g ...
- spring学习笔记(七)HttpMessageConverter
spring学习笔记(七)HttpMessageConverter 1. HttpMessageConverter的加载 2. 从StringMessageConverter探究消息转换器的原理 1. ...
- Spring学习之旅(十)--MockMvc
在之前的 Spring学习之旅(八)--SpringMVC请求参数 我们是通过在控制台输出来验证参数是否正确,但是这样做实在是太耗时间了,我们今天来学习下 MockMvc,它可以让我们不需要启动项目就 ...
随机推荐
- 【app】自动化环境搭建(Appium)for java
Appium来做app自动化相信大家都很熟悉了吧,就不再赘述他的概念和作用了,我们接下来着重介绍怎么来搭建整个app自动化环境,整个环境包括如下几个步骤: 1.安装jdk和eclipse及配置jdk的 ...
- [EXP]windows全版本SMB溢出工具加强版
工具:k8加强版zzz 编译:python 漏洞:MS17-010 用法: zzz_exploit.exe 192.11.22.82zzz_exploit.exe 192.11.22.82 exe参数 ...
- JS获取链接中域名等信息
以访问百度为例子http://pan.baidu.com/share/qrcode?w=150&h=150&url=http%3A%2F%2F172.16.1.96%2FWeb%2FG ...
- mysql 开发进阶篇系列 55 权限与安全(安全事项 )
一. 操作系统层面安全 对于数据库来说,安全很重要,本章将从操作系统和数据库两个层面对mysql的安全问题进行了解. 1. 严格控制操作系统账号和权限 在数据库服务器上要严格控制操作系统的账号和权限, ...
- mysql 开发进阶篇系列 50 表的数据导入(load data infile,mysqlimport )
一.概述 上篇讲到的表的数据导出(select .. into outfile 或者mysqldump),这篇继续讲表的数据导入,导入也同样有二个方法,分别是load data infile... 和 ...
- C# 获取 sha256
C# 获取 sha256, 输入可以是 字符串,也可以是 字节流流: 自定义的输入类型的枚举: public enum Sha26ParseType { StringType, StreamType ...
- SpringCloud2.0入门4-springboot-admin监控
前言 上一节为springboot项目添加springboot-admin监控 学习了基于springboot1.5自己注册到admin的方法.接下来学习结合Eureka使用以及2.0的改变. 1.5 ...
- 32位汇编第五讲,逆向实战干货,(OD)快速定位扫雷内存.
32位第五讲,逆向实战干货,快速定位扫雷内存. 首先,在逆向之前,大家先对OD有一个认识. 一丶OD的使用 标号1: 反汇编窗口 (显示代码的地址,二进制指令,汇编代码,注释) 标号2: 寄存器窗口( ...
- 开源任务调度平台elastic-job-lite源码解析
前段时间写过一遍文章<一文揭秘定时任务调度框架quartz>,有读者建议我再讲讲elastic-job这个任务调度框架,年末没有那么忙,就来学习一下elastic-job. 首先一点,el ...
- 分享几个实用的Chrome扩展程序
前言 吐槽一下自己,最近变懒了,博客已经变成月更了.这次分享几个自己工作这几年下来,平常用的比较多的几个谷歌浏览器的扩展程序. AdBlock 最受欢迎的 Chrome 扩展,拥有超过 6000 万用 ...