2017-11-10 21:25:02

Spring的AspectJ的AOP
AspectJ 是一个面向切面的框架,它扩展了 Java 语言。 AspectJ 定义了 AOP 语法所以它有一个专门的编译器用来生成遵守 Java 字节编码规范的 Class 文件。
AspectJ 是一个基于 Java 语言的 AOP 框架,Spring2.0 以后新增了对 AspectJ 切点表达式支持
@AspectJ  是 AspectJ1.5 新增功能,通过 JDK5 注解技术,允许直接在 Bean 类中定义切面
新版本 Spring 框架,建议使用 AspectJ 方式来开发 AOP。

  • AspectJ 表达式

在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点"。

execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?)  

除了返回类型模式、方法名模式和参数模式外,其它项都是可选的

实例:

execution (* com.sample.service.impl..*.*(..))
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个*号:表示返回类型,*号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。 execution(“* cn.spring3.demo1.dao.*(..)”) --- 只匹配当前包
execution(“* cn.spring3.demo1.dao..*(..)”) --- 匹配包及当前包的子包 .
execution(* cn.dao.GenericDAO+.*(..)) --- 匹配 GenericDAO 及子类
execution(* save*(..)) ---匹配所有save开头的方法
  • AspectJ增强方式

@Before  前置通知,相当于 BeforeAdvice
@AfterReturning  后置通知,相当于 AfterReturningAdvice
@Around  环绕通知,相当于 MethodInterceptor
@AfterThrowing 抛出通知,相当于 ThrowAdvice
@After  最终 final 通知,不管是否异常,该通知都会执行
@DeclareParents  引介通知,相当于 IntroductionInterceptor

一、基于注解的方式

开发步骤:

  • 第一步 : 引入相应 jar 包
    * aspectj 依赖 aop 环境 .
    * spring-aspects-3.2.0.RELEASE.jar
    * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
  • 第二步 : 编写目标类
  • 第三步 : 使用AspectJ注解自定义切面类,就是切点与增强结合
  • 第四步 : 配置XML
    *  引入 aop 的约束 :
    * <aop:aspectj-autoproxy /> ---  自动生成代理 :
    *  底层就是 AnnotationAwareAspectJAutoProxyCreator
// 类
public class Student {
public void add(){
System.out.println("添加方法...");
} public void delete(){
System.out.println("删除方法...");
}
} // 切面
@Aspect
public class MyAspect {
@Before("execution(* spring2..*.add*(..))")
void before(){
System.out.println("前置增强...");
}
} // 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:config3.xml")
public class Demo { @Resource(name = "stu")
private Student s;
@Test
public void demo(){
s.add();
}
}

配置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"> <!--自动生成代理,底层就是 AnnotationAwareAspectJAutoProxyCreator-->
<aop:aspectj-autoproxy/> <bean id="stu" class="spring2.Student"/> <!--需要把切面类进行注册,才能自动生成代理-->
<bean id="myaspect" class="spring2.MyAspect"/>
</beans>

* 其他的增强的使用:

AspectJ的通知类型:
@Before 前置通知,相当于BeforeAdvice
* 就在方法之前执行.没有办法阻止目标方法执行的.
@AfterReturning 后置通知,相当于AfterReturningAdvice
* 后置通知,获得方法返回值.
@Around 环绕通知,相当于MethodInterceptor
* 在可以方法之前和之后来执行的,而且可以阻止目标方法的执行.
@AfterThrowing 抛出通知,相当于ThrowAdvice
@After 最终final通知,不管是否异常,该通知都会执行
@DeclareParents 引介通知,相当于IntroductionInterceptor

@Aspect
public class MyAspect {
@Before("execution(* spring2..*.add*(..))")
void before() {
System.out.println("前置增强...");
} @AfterReturning(value = "execution(* spring2..*.add*(..))", returning = "returnVal")
public void afterReturning(Object returnVal) {
System.out.println("后置增强..." + "方法的返回值:" + returnVal);
} @Around("execution(* spring2..*.add*(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕前增强...");
Object object = proceedingJoinPoint.proceed();
System.out.println("环绕后增强...");
return object;
} @AfterThrowing(value = "execution(* spring2..*.add*(..))", throwing = "e")
public void throwing(Throwable e) {
System.out.println("不好,出异常了!" + e.getMessage());
} @After("execution(* spring2..*.add*(..))")
public void after() {
System.out.println("最终通知...");
}
}

* 基于AspectJ的切点定义

使用 @Pointcut 进行自定义的切点定义。

@Aspect
public class MyAspect {
@Before("MyAspect.myPointcut()")
void before() {
System.out.println("前置增强...");
} @Pointcut("execution(* spring2..*.add*(..))")
private void myPointcut(){}
}

* Advisor和Aspect的区别

Advisor:Spring传统意义上的切面:支持一个切点和一个通知的组合.
Aspect:可以支持多个切点和多个通知的组合.

二、基于XML的方式

/**
* 切面类
*/
public class MyAspectXML {
public void before() {
System.out.println("前置通知...");
} public void afterReturing(Object returnVal) {
System.out.println("后置通知...返回值:" + returnVal);
} public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕前增强....");
Object result = proceedingJoinPoint.proceed();
System.out.println("环绕后增强....");
return result;
} public void afterThrowing(Throwable e) {
System.out.println("异常通知..." + e.getMessage());
} public void after() {
System.out.println("最终通知....");
}
}

XML配置:

<!-- 定义切面 -->
<bean id="myAspect" class="spring2.MyAspect"></bean>
<!-- 定义aop配置 -->
<aop:config>
<!-- 定义切点: -->
<aop:pointcut expression="execution(* cn.itcast.spring3.demo2.ProductDao.add(..))" id="mypointcut"/>
<aop:aspect ref="myAspect">
<!-- 前置通知 -->
<!-- <aop:before method="before" pointcut-ref="mypointcut"/> -->
<!-- 后置通知 -->
<!-- < aop:after -returning method="afterReturing" pointcut-ref="mypointcut" returning="returnVal"/> -->
<!-- 环绕通知 -->
<!-- < aop:around method="around" pointcut-ref="mypointcut"/> -->
<!-- 异常通知 -->
<!-- < aop:after-throwing method="afterThrowing" pointcut-ref="mypointcut" throwing="e"/> -->
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="mypointcut"/>
</aop:aspect>
</aop:config>

Java Spring-AspectJ的更多相关文章

  1. Java Spring的IoC和AOP的知识点速记

    Spring简介 Spring解决的最核心的问题就是把对象之间的依赖关系转为用配置文件来管理,这个是通过Spring的依赖注入机制实现的. Spring Bean装配 1. IOC的概念以及在Spri ...

  2. 从零开始学 Java - Spring AOP 实现主从读写分离

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  3. Java Spring AOP用法

    Java Spring AOP用法 Spring AOP Java web 环境搭建 Java web 项目搭建 Java Spring IOC用法 spring提供了两个核心功能,一个是IoC(控制 ...

  4. Spring AspectJ AOP 完整示例

    http://outofmemory.cn/java/spring/AOP/aop-aspectj-example-before-after-AfterReturning-afterThrowing- ...

  5. Spring(十二)--Spring AspectJ

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

  6. 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)

    Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...

  7. 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)

    你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...

  8. 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)

    硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...

  9. 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)

    从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...

  10. 从零开始学 Java - Spring 支持 CORS 请求踩的坑

    谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...

随机推荐

  1. 详探TextRange对象--查找与选择(转载)

    TextRange对象是动态HTML(DHTML)的高级特性,使用它可以实现很多和文本有关的任务,例如搜索和选择文本.文本范围让您可以选择性的将字符.单词和句子从文档中挑选出来.TextRange对象 ...

  2. vue 引入通用 css

    1.在入口 js 文件 main.js 中引入,一些公共的样式文件,可以在这里引入. import Vue from 'vue' import App from './App' // 引入App这个组 ...

  3. poj1952 BUY LOW, BUY LOWER【线性DP】【输出方案数】

    BUY LOW, BUY LOWER Time Limit: 1000MS   Memory Limit: 30000K Total Submissions:11148   Accepted: 392 ...

  4. nginx + ngx_lua安装测试

    nginx lua模块淘宝开发的nginx第三方模块,它能将lua语言嵌入到nginx配置中,从而使用lua就极大增强了nginx的能力.nginx以高并发而知名,lua脚本轻便,两者的搭配堪称完美. ...

  5. Magento 2 初探

    进入公司有一小段时间了,虽然自己之前一直从事前端工作,但是基本工作就是做一些国内电商网站的前端工作.在刚进入这家公司时,自己对 magento2 一无所知,尽管上班前看过老大发给我的一些文档资料,但是 ...

  6. Elasticsearch入门教程

    ElasticSearch是一个高度可扩展的开源搜索引擎并使用REST API,所以您值得拥有. 在本教程中,将介绍开始使用ElasticSearch的一些主要概念. 下载并运行ElasticSear ...

  7. 1.Anaconda安装Tensorflow报错UnicodeDecodeError: 'utf-8' codec can't decode ## invalid start byte的问题之解决

    安装TensorFlow pip install --ignore-installed --upgrade tensorflow 报错: UnicodeDecodeError: 'utf-8' cod ...

  8. Spark Core (一) 什么是RDD的Transformation和Action以及Dependency(转载)

    1. Spark的RDD RDD(Resilient Distributed Datasets),弹性分布式数据集,是对分布式数据集的一种抽象. RDD所具备5个主要特性: 一组分区列表 计算每一个数 ...

  9. Jitamin

    安装环境要求 PHP 5.6或更高(推荐使用PHP7) 数据库, 推荐使用MySQL 或 PostgreSQL. 当然SQLite也可以运行. Composer 安装手册 一. 克隆代码 假设我们把j ...

  10. C++中的RAII介绍 资源管理

    摘要 RAII技术被认为是C++中管理资源的最佳方法,进一步引申,使用RAII技术也可以实现安全.简洁的状态管理,编写出优雅的异常安全的代码. 资源管理 RAII是C++的发明者Bjarne Stro ...