spring9——AOP之AspectJ对AOP的实现
从上述的实验中可以看出BeanNameAutoProxyCreator对于AOP的实现已经和完美了,但是还有两点不足之处:
1,对于切面的实现比较麻烦,既不同类型的通知切面要实现不同的接口,而且一个切面只有一个方法。
2,对于切入点的实现也不是很完美,既通知实现的切面对象的方法对于目标对象方法的精确织入要使用不同的顾问进行包装实现。
在以上的试验中,我们不难看出,其实对于切面的的实现就是切面方法向目标对象方法织入的过程。
那么提出两个问题:
1,可不可以让一个类去实现不同类型通知的功能,既一个类中有多个方法,可以让我们指定方法的的通知类型。
2,对于切入点的实现能不能规定一种切入点表达式,可以对目标对象的方法进行切入点的指定,免去使用多个顾问对不同通知包装的麻烦。
针对以上两点,AspectJ框架这个框架给出了很好的解决方案,而AspectJ框架又是属于spring框架的一部分。
我们这里依旧通过实验来说明问题,还是用之前实验的例子。
用于创建目标对象的接口和实现类。
public interface ICalculatorService { int add(int a,int b); int division(int a ,int b); }
public interface IComparatorService { void comparator(int a,int b);
}
public class CalculatorServiceImpl implements ICalculatorService { @Override
public int add(int a, int b) {
return a+b;
} @Override
public int division(int a, int b) {
return a/b;
} }
public class ComparatorServiceImpl implements IComparatorService { @Override
public void comparator(int a, int b) { if(a > b){
System.out.println(a+"比"+b+"大");
}else if(a < b){
System.out.println(a+"比"+b+"小");
}else{
System.out.println(a+"等于"+b);
} } }
切面的实现类,AspectJ框架允许我们的切面是一个POJO类,这样就避免了spring框架Api的侵染,另外AspectJ框架比之前多出了一个最终通知,就是不管目标方法执行与否,最终通知的方法都会执行,有点类似finally语句快。
public class MyAspect {
//前置通知方法
public void myBefore() {
System.out.println("执行前置通知方法");
}
// 后置通知方法
public void myAfterReturning() {
System.out.println("执行后置通知方法");
}
// 环绕通知方法
public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("执行环绕通知方法");
Object[] args = pjp.getArgs();
int a = (int)args[0];
int b = (int)args[1];
if(b == 0){
System.err.println("除数不能为0");
return -1;
}
if(a == 0){
return 0;
}
return pjp.proceed();
}
// 最终通知
public void myAfter() {
System.out.println("执行最终通知");
} }
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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 目标对象 -->
<bean id="comparatorServiceTarget" class="com.opensource.service.impl.ComparatorServiceImpl"/>
<bean id="calculatorServiceTarget" class="com.opensource.service.impl.CalculatorServiceImpl"/>
<!-- 通知 -->
<bean id="myAspect" class="com.opensource.service.MyAspect"/>
<!-- AOP配置 -->
<aop:config>
<aop:pointcut expression="execution(* *..service.*.*(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* *..ICalculatorService.division(..))" id="pointcut2"/> <aop:aspect ref="myAspect">
<aop:before method="myBefore" pointcut-ref="pointcut1"/> <aop:after-returning method="myAfterReturning" pointcut-ref="pointcut1"/> <aop:around method="myAround" pointcut-ref="pointcut2"/> <aop:after method="myAfter" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config> </beans>
AspectJ框架提供的标签可以让我们指定切面中不同的方法的通知类型,二切入点表达式则允许我们对该切面方法要织入spring容器中的那些目标对象,及对象的那些方法(切入点)。对于切入点表达式的使用这里介绍两种最常用的:
//指定工程中所有包下子包为service的接口和实现类为切入点
<aop:pointcut expression="execution(* *..service.*.*(..))" id="pointcut1"/> //指定工程中所有包下接口名为ICalculatorService及其实现类的division方法为切入点
<aop:pointcut expression="execution(* *..ICalculatorService.division(..))" id="pointcut2"/>
你若是想对工程中某个具体的接口或者实现类的方法进行指定就要采用如下做法
这里注意*号后的空格不能少
<aop:pointcut expression="execution(* com.opensource.service.ICalculatorService.division(..))" id="pointcut2"/>
另外切入点表达式同样支持模糊匹配的方式。
测试类:
public class MyTest {
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("spring-bean.xml");
ICalculatorService bean = (ICalculatorService)ac.getBean("calculatorServiceTarget");
IComparatorService bean1 = (IComparatorService)ac.getBean("comparatorServiceTarget");
int division = bean.division(10, 2);
System.out.println("两数相除商为:"+division);
System.err.println("---------------------------------------------------------");
int add = bean.add(0, 2);
System.out.println("两数想加和为:"+add);
System.err.println("---------------------------------------------------------");
bean1.comparator(0, 1); } }
实验结果:
AspectJ框架对于Aop的实现配置比较简单,实现上也很灵活,还支持注解式开发,本文用到的式配置式开发,另外还有对于切面方法参数的配置,还有很多点。
最后说一点,我们作为程序员,研究问题还是要仔细深入一点的。当你对原理了解的有够透彻,开发起来也就得心应手了,很多开发中的问题和疑惑也就迎刃而解了,而且在面对其他问题的时候也可做到触类旁通。当然在开发中没有太多的时间让你去研究原理,开发中要以实现功能为前提,可等项目上线的后,你有大把的时间或者空余的时间,你大可去刨根问底,深入的去研究一项技术,为觉得这对一名程序员的成长是很重要的事情。
spring9——AOP之AspectJ对AOP的实现的更多相关文章
- Spring -- aop, 用Aspectj进行AOP开发
1. 概要 添加类库:aspectjrt.jar和aspectjweaver.jar 添加aop schema. 定义xml元素:<aop:aspectj-autoproxy> 编写jav ...
- spring3: schema的aop与Aspectj的aop的区别
schema的aop如下: 接口: package chapter6.service; public interface IHelloAroundService { public void sayAr ...
- 第三章 AOP 基于@AspectJ的AOP
在前面,我们分别使用Pointcut.Advice.Advisor接口来描述切点.增强.切面.而现在我们使用@AdpectJ注解来描述. 在下面的例子中,我们是使用Spring自动扫描和管理Bean. ...
- Spring框架(6)---AspectJ实现AOP
AspectJ实现AOP 上一篇文章Spring框架(4)---AOP讲解铺垫,讲了一些基础AOP理解性的东西,那么这篇文章真正开始讲解AOP 通过AspectJ实现AOP要比普通的实现Aop要方便的 ...
- 比较 Spring AOP 与 AspectJ
本文翻译自博客Comparing Spring AOP and AspectJ(转载:https://juejin.im/post/5a695b3cf265da3e47449471) 介绍 如今有多个 ...
- Spring @AspectJ 实现AOP 入门例子(转)
AOP的作用这里就不再作说明了,下面开始讲解一个很简单的入门级例子. 引用一个猴子偷桃,守护者守护果园抓住猴子的小情节. 1.猴子偷桃类(普通类): package com.samter.common ...
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
- AspectJ对AOP的实现
一:你应该明白的知识 1.对于AOP这种编程思想,很多框架都进行了实现.Spring就是其中之一,可以完成面向切面编程.然而,AspectJ也实现了AOP的功能,且实现方式更为简捷,使用更加方便,而且 ...
- 基于@AspectJ和schema的aop(二)---@AspectJ基础语法
@AspectJ使用jdk5.0和正规的AspectJ切点表达式描述切面, 由于spring只支持方法的连接点,所以Spring只支持部分AspectJ的切点语言. 1.切点表达式函数 AspectJ ...
随机推荐
- cookie 使用方法
//写cookies setCookie: function(name, value) { let days = 1 let exp = new Date() exp.setTime(exp.getT ...
- win8快捷键
win+Q/S搜索所有位置 win+W搜索设置 win+E文件资源管理器 win+R运行 win+T选中第一个应用程序(不确定) win+U轻松使用设置中心 win+I设置 win+P投影 win+D ...
- vue单页页面开发教程及注意事项
如下图: 1.安装node.js webpack node -v 查看版本 webpack -v 2.安装脚手架 vue-cli npm install -g vue-cli 3. 在项目文件夹创 ...
- angularjs常用事件
1. 视图模板加载完毕 $scope.$on('$viewContentLoaded', function() { alert('view template loaded'); });
- 数据系统的未来------《Designing Data-Intensive Applications》读书笔记17
终于来到这本书最后的一章了<Designing Data-Intensive Applications>大部头,这本书应该是我近两年读过最棒的技术书籍.作者Martin Kleppmann ...
- mysql主从复制安装详解
1.环境准备:两台Linux6.8服务器,(可以通过yum安装mysql:yum install mysql mysql-server -y,安装的版本可能比较低,对于练手来说够用了 )主库ip:19 ...
- RabbitMQ 消息确认与公平调度消费者
一.消息确认 为了确保消息一定被消费者处理,rabbitMQ提供了消息确认功能,就是在消费者处理完任务之后,就给服务器一个回馈,服务器就会将该消息删除,如果消费者超时不回馈,那么服务器将就将该消息重新 ...
- Algorithm --> 邮票连续组合问题
邮票组合问题 有四种面值的邮票很多枚,面值分别为1,4,12,21,取五张,求取出这些邮票的最大连续组合值 代码: #include <stdio.h> #include <stri ...
- cocos对lua代码加密
1.0 cocos luacompile 用法 我用的普通的cocos2d lua,没用quick,quick好像可以对整个资源包括图像和音频都加密,打包成zip.但我没用quick.看了下luaco ...
- 使用Python中的mock模块进行单元测试
在进行单元测试的时候,有时候会遇到这种情况: 出于某些原因,我们不想测试某一部分内容,但是我们想要测试的部分却依赖这部分内容. 这时候,可以使用mock模块来模拟调用这部分内容,并给出返回结果,举例如 ...