一、AspectJ、Spring与AOP的关系

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。(百度百科)

Spring又将AspectJ的对于AOP的实现引入到自己的框架中。

在Spring中使用AOP开发时,一般使用AspectJ的实现方式。

二、AspectJ的通知类型

  1. 前置通知
  2. 后置通知
  3. 环绕通知
  4. 异常通知
  5. 最终通知

三、AspectJ的切入点表达式


表达式中加【】的部分表示可省略部分 ,个部分用空格分开。在其中可以使用以下符号:

execution(* * ..service.*.*(..))

指定所有包下的service子包下所有类(接口)中所有方法为切入点

execution(* *..ISomeService.*(..))

指定所有包下的ISomeService接口中所有方法为切入点

三、AspectJ的开发环境


导入2个Jar包

spring-framework-3.0.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE

四、AspectJ基于注解的AOP实现

1、前置通知

 //主业务接口
public interface ISomeService {
//目标方法
void doFirst();
String doSecond();
void doThird(); }

ISomeService

 public class SomeServiceImpl implements ISomeService {

     @Override
public void doFirst() {
// TODO Auto-generated method stub
System.out.println("执行doFirst()方法");
} @Override
public String doSecond() {
// TODO Auto-generated method stub
System.out.println("执行doSecond()方法");
return "abcde";
} @Override
public void doThird() {
// TODO Auto-generated method stub
System.out.println("执行doThird()方法");
} }

SomeServiceImpl

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; @Aspect //表示当前类为切面
public class MyAspect {
@Before("execution(* *..ISomeService.doFirst(..))")
public void before(){
System.out.println("执行前置通知方法");
} @Before("execution(* *..ISomeService.doFirst(..))")
public void before(JoinPoint jp){
System.out.println("执行前置通知方法 jp="+jp);
} }

MyAspect

 import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test
public void test01() {
//创建容器对象
String resource = "com/bjpowernode/annotation/applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(resource); ISomeService service=(ISomeService) ac.getBean("someService");
service.doFirst();
System.out.println("--------------------");
service.doSecond();
System.out.println("--------------------");
service.doThird();
} }

MyTest

 <?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 id="myAspect" class="com.bjpowernode.annotation.MyAspect"></bean> <!-- 注册目标对象 -->
<bean id="someService" class="com.bjpowernode.annotation.SomeServiceImpl"></bean> <!-- 注册AspectJ的自动代理 -->
<aop:aspectj-autoproxy/>
</beans>

ApplicationContext

输出:

执行前置通知方法
执行前置通知方法 jp=execution(void com.bjpowernode.annotation.ISomeService.doFirst())
执行doFirst()方法
--------------------
执行doSecond()方法
--------------------
执行doThird()方法

output

2.后置通知

   @AfterReturning("execution(* *..ISomeService.doSecond(..))")
public void myAfterReturning(){
System.out.println("执行后置通知方法"); } @AfterReturning(value="execution(* *..ISomeService.doSecond(..))",returning="result")
public void myAfterReturning(Object result){
System.out.println("执行后置通知方法 result="+result); }

MyAspect

3、环绕通知

    @Around("execution(* *..ISomeService.doSecond(..))")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("执行环绕通知方法,目标方法执行之前");
//执行目标方法
Object result = pjp.proceed();
System.out.println("执行环绕通知方法,目标方法执行之后");
return result; }

MyAspect

输出:

 执行环绕通知方法,目标方法执行之前
执行doSecond()方法
执行环绕通知方法,目标方法执行之后

output

4、异常通知

  @AfterThrowing("execution(* *..ISomeService.doThird(..))")
public void myAfterThrowing(){
System.out.println("执行异常通知方法");
}

MyAspect

   @AfterThrowing(value="execution(* *..ISomeService.doThird(..))",throwing="ex")
public void myAfterThrowing(Exception ex){
System.out.println("执行异常通知方法ex="+ex.getMessage());
}

MyAspect

 执行异常通知方法ex=/ by zero

output

5、最终通知

  @After("execution(* *..ISomeService.doThird(..))")
public void myAfter(){
System.out.println("执行最终通知方法");
}

五、定义切入点

定义了一个切入点,叫doThirdPointcut()

  @After("doThirdPointcut()")
public void myAfter(){
System.out.println("执行最终通知方法");
}
//定义了一个切入点,叫doThirdPointcut()
@Pointcut("execution(* *..ISomeService.doThird(..))")
public void doThirdPointcut(){}
}

Spring_Spring与AOP_AspectJ基于注解的AOP实现的更多相关文章

  1. Spring基础知识之基于注解的AOP

    背景概念: 1)横切关注点:散布在应用中多处的功能称为横切关注点 2)通知(Advice):切面完成的工作.通知定了了切面是什么及何时调用. 5中可以应用的通知: 前置通知(Before):在目标方法 ...

  2. spring中基于注解使用AOP

    本文内容:spring中如何使用注解实现面向切面编程,以及如何使用自定义注解. 一个场景 比如用户登录,每个请求发起之前都会判断用户是否登录,如果每个请求都去判断一次,那就重复地做了很多事情,只要是有 ...

  3. AspectJ框架基于注解的AOP实现

    AspectJ的AOP实现:有两种方式,一种是基于XML配置文件,一种是基于注解的,由于注解更为常用,这里 这里只针对注解来学习. ---------------------------------- ...

  4. 阶段3 2.Spring_08.面向切面编程 AOP_9 spring基于注解的AOP配置

    复制依赖和改jar包方式 src下的都复制过来. 复制到新项目里了 bean.xml里面复制上面一行代码到下面.把aop改成context. 配置spring容器创建时要扫描的包 Service的配置 ...

  5. springboot自定义jdbc操作库+基于注解切点AOP

    发布时间:2018-11-08   技术:springboot+aop   概述 springBoot集成了自定义的jdbc操作类及AOP,因为spring自带的JdbcTemplate在实际项目中并 ...

  6. Spring AspectJ基于注解的AOP实现

    对于AOP这种编程思想,很多框架都进行了实现.Spring就是其中之一,可以完成面向切面编程.然而,AspectJ也实现了AOP的功能,且实现方式更为简捷,使用更加方便,而且还支持注解式开发.所以,S ...

  7. Spring 基于注解的AOP实现

    在本文开始之前,我要引入一张图,这张图的来源 https://blog.csdn.net/chenyao1994/article/details/79708496 ,版权归原作者所有,我借鉴了原作者的 ...

  8. Spring_Spring与IoC_基于注解的DI

    一.基本注解的使用 (1)导入AOP的Jar包 (2) 与set()无关 二.组件扫描器的base-package 三.@Component相关注解 四.@Scope 五.域属性的注入 (1)byTy ...

  9. 基于注解的AOP配置

    配置文件 spring配置文件中的约束 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ...

随机推荐

  1. DLL导出全局变量在多个DLL中调用

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  2. Git学习(2)-使用Git 代码将本地文件提交到 GitHub

    上次随笔写到git的安装和运用命令窗口创建本地版本库,这次主要讲一下用git代码将本地文件提交到GitHub上. 前提是有一个GitHub账号. 1.创建一个新的版本库,进入到你本地项目的根目录下(我 ...

  3. jstl 的判断使用

    JSTL  是JSP的标准标记库 1.必须引入的头部标签 <%@ taglib uri="http://java.sun.com/jstl/core_rt"prefix=&q ...

  4. python_如何通过实例方法名字调用方法?

    案例: 某项目中,我们的代码使用的2个不同库中的图形类: Circle,Triangle 这两个类中都有一个获取面积的方法接口,但是接口的名字不一样 需求: 统一这些接口,不关心具体的接口,只要我调用 ...

  5. secureCRT sftp使用

    sftp-- help 可用命令: cd 路径 更改远程目录到"路径" lcd 路径 更改本地目录到"路径" chgrp group path 将文件" ...

  6. PHP中变量的销毁

    PHP的变量或对象的销毁可以分成显式销毁和隐式销毁: 1.显式销毁,当对象没有被引用时就会被销毁,所以我们可以unset或为其赋值NULL; 2.隐式销毁,PHP是脚本语言,在代码执行完最后一行时,所 ...

  7. redis数据类型-列表类型

    列表类型 列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段. 列表类型内部是使用双向链表(double linked list)实现的,所以向 ...

  8. HTML5之Notification简单使用

    var webNotification = { init: function() { if(!this.isSupport()) { console.log('不支持通知'); return; } t ...

  9. Cypher查询语言--Neo4j 之高级篇 (六)

    目录 排序Order by 通过节点属性排序节点 通过多节点属性排序节点 倒序排列节点 空值排序 Skip 跳过前三个 返回中间两个 Limit 返回第一部分 函数Functions 判断 All A ...

  10. Trusted Execution Technology (TXT) --- 启动控制策略(LCP)篇

    版权声明:本文为博主原创文章,未经博主允许不得转载.http://www.cnblogs.com/tsec/p/8428631.html 在TXT平台中,启动控制策略(Launch Control P ...