从上述的实验中可以看出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. Linux中安装字体

    Linux中安装字体 查看系统中的字体 fc-list 查看系统中的中文字体 fc-list :lang=zh将然后将字体文件拷贝到/usr/share/fonts/中 cp aa.ttl /usr/ ...

  2. centos6.x上安装Java-1.8.0

    author : headsen chen date : 2017-12-04  10:32:44 notice :This  article is created by headsen chen h ...

  3. java 二叉树排序

    1 class BinaryTree{ 2 class Node{ 3 private Comparable data; 4 private Node left; 5 private Node rig ...

  4. python全栈学习--day1

      计算机基础 CPU:中央处理器 内存:4GB,8GB,临时处理事务的地方,供给CPU数据. 硬盘:相当于电脑的数据库,存储着大量的数据,文件,电影等. 操作系统:执行者,支配所有关系 window ...

  5. RDD概念、特性、缓存策略与容错

    一.RDD概念与特性 1. RDD的概念 RDD(Resilient Distributed Dataset),是指弹性分布式数据集.数据集:Spark中的编程是基于RDD的,将原始数据加载到内存变成 ...

  6. 【Spring系列】自己手写一个 SpringMVC 框架

    参考文章 一.了解SpringMVC运行流程及九大组件 1.SpringMVC的运行流程 1)用户发送请求至前端控制器DispatcherServlet 2)DispatcherServlet收到请求 ...

  7. C语言程序设计(基础)- 第6周作业

    一.PTA作业 完成PTA第六周作业中4个题目的思路列在博客中. 1.7-1 高速公路超速处罚 2.7-2 计算油费 3.7-3 比较大小 4.7-4 两个数的简单计算器 (必须使用switch结构实 ...

  8. Alpha第四天

    Alpha第四天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...

  9. 1013团队alpha冲刺日志集合帖

    alpha冲刺day1 alpha冲刺day2 alpha冲刺day3 alpha冲刺day4 alpha冲刺day5 alpha冲刺day6 alpha冲刺day7 alpha冲刺day8 alph ...

  10. python实现京东秒杀

    # _*_coding:utf-8_*_ from selenium import webdriver import datetime import time driver = webdriver.C ...