从上述的实验中可以看出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的实现的更多相关文章

  1. Spring -- aop, 用Aspectj进行AOP开发

    1. 概要 添加类库:aspectjrt.jar和aspectjweaver.jar 添加aop schema. 定义xml元素:<aop:aspectj-autoproxy> 编写jav ...

  2. spring3: schema的aop与Aspectj的aop的区别

    schema的aop如下: 接口: package chapter6.service; public interface IHelloAroundService { public void sayAr ...

  3. 第三章 AOP 基于@AspectJ的AOP

    在前面,我们分别使用Pointcut.Advice.Advisor接口来描述切点.增强.切面.而现在我们使用@AdpectJ注解来描述. 在下面的例子中,我们是使用Spring自动扫描和管理Bean. ...

  4. Spring框架(6)---AspectJ实现AOP

    AspectJ实现AOP 上一篇文章Spring框架(4)---AOP讲解铺垫,讲了一些基础AOP理解性的东西,那么这篇文章真正开始讲解AOP 通过AspectJ实现AOP要比普通的实现Aop要方便的 ...

  5. 比较 Spring AOP 与 AspectJ

    本文翻译自博客Comparing Spring AOP and AspectJ(转载:https://juejin.im/post/5a695b3cf265da3e47449471) 介绍 如今有多个 ...

  6. Spring @AspectJ 实现AOP 入门例子(转)

    AOP的作用这里就不再作说明了,下面开始讲解一个很简单的入门级例子. 引用一个猴子偷桃,守护者守护果园抓住猴子的小情节. 1.猴子偷桃类(普通类): package com.samter.common ...

  7. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  8. AspectJ对AOP的实现

    一:你应该明白的知识 1.对于AOP这种编程思想,很多框架都进行了实现.Spring就是其中之一,可以完成面向切面编程.然而,AspectJ也实现了AOP的功能,且实现方式更为简捷,使用更加方便,而且 ...

  9. 基于@AspectJ和schema的aop(二)---@AspectJ基础语法

    @AspectJ使用jdk5.0和正规的AspectJ切点表达式描述切面, 由于spring只支持方法的连接点,所以Spring只支持部分AspectJ的切点语言. 1.切点表达式函数 AspectJ ...

随机推荐

  1. 微信小程序学习笔记(阶段一)

    一阶段学习过程: (一)看官方文档的简易教程:https://mp.weixin.qq.com/debug/wxadoc/dev/ (二)看小码哥视频:https://chuanke.baidu.co ...

  2. 使用Intellij IDEA生成JavaDoc

    以下是常用的注释标签,规范书写生成的文档中才能显示: @author 作者 @version 版本 @see 参考转向 @param 参数说明 @return 返回值说明 @exception 异常说 ...

  3. npm5 packag-lock.json

    前几天升级了 Node.js v8.0 后,自带的 npm 也升级到了5.0,第一次使用的时候确实惊艳到了:原本重新安装一次模块要十几秒到事情,现在一秒多就搞定了.先不要激动,现在我来大概讲一下 np ...

  4. JSON字符串转为JSON对象

    在数据传输流程中,json是以文本,即字符串的形式传递的,而JS操作的是对象,所以,JSON对象(js对象)和JSON字符串之间的相互转换是关键. JSON可以有两种格式,一种是对象格式的,另一种是数 ...

  5. 后台返回null iOS

    1.第一种解决方案 就是在每一个 可能传回null 的地方 使用  if([object isEqual:[NSNUll null]]) 去判断 2.第二种解决方案 网上传说老外写了一个Categor ...

  6. 查看Linux内核版本之lsb_release

    lsb_release命令LSB是Linux Standard Base的缩写,lsb_release命令用来显示LSB和特定版本的相关信息,可通过yum -y install redhat-lsb命 ...

  7. C#基础(二)拆箱与装箱,循环与选择结构,枚举

    一.装箱和拆箱 装箱是将值类型转换为引用类型 eg: Int a=5; Object  o=a; 拆箱是将引用类型转换为值类型 eg: Int a=5; Object  o=a; Int b=(int ...

  8. IDEA配置Struts框架

    对于刚接触编程的同学,对框架只是还不是很了解,本文主要介绍在Idea上配置Struts,实现简单的页面跳转,以及页面参数传递. 在进行代码编写之前先对Idea进行一个简单了解,对于长时间接触编程的,对 ...

  9. JavaScript Alert 函数执行顺序问题

    * { color: #3e3e3e } body { font-family: "Helvetica Neue", Helvetica, "Hiragino Sans ...

  10. 实验MyOD

    实验MyOD 编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 提交测试代码和运行结果截图,加上学号水印,提交码云代码链接. 代码如下: (刚开始 ...