spring---aop(10)---Spring AOP中AspectJ
写在前面
在之前的文章中有写到,Spring在配置中,会存在大量的切面配置。然而在很多情况下,SpringAOP 所提供的切面类真的不是很够用,比如想拦截制定的注解方法,我们就必须扩展DefalutPointAdviso类,自定义一个切面类,然后在Spring配置文件中进行切面的配置。
(Spring+AspectJ) Spring集成了AspectJ,同时保留了以上提到的切面与代理配置方式(为了兼容老的项目)。
使用AspectJ需要引入对于的jar文件
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>
Spring + AspectJ(基于注解:通过AspectJ execution 表达式拦截方法)
下面以一个最简单的例子来实现之前提到的环绕同一种。先定义一个Aspect切面类:
@Aspect
@Component
public class GreetingAspect {
@Around("execution(* aop.demo.GreetingImpl.*())")
public Object arount(ProceedingJoinPoint pjp) throws Throwable{
before();
Object obj = pjp.proceed();
after();
return obj;
}
private void after() {
System.out.println("before advice");
}
private void before() {
System.out.println("after advice");
}
}
注意:类上面标志的Aspect注解表明该类是一个Aspect(在Spring 体系这个其实就是一个Advisor)。该类无须实现任何接口,只需要定义一个方法(名称无所谓),在方法上标注Arount注解,在注解中共使用AspectJ 切点表达式。方法中的参数包括一个ProceedingJoinPoint对象,它在AOP 体系中成为Joinpoint(连接点),可以通过该对象获取方法的任何信息。
分析一个这个切点表达式 execution(* aop.demo.GreetingImpl.*())
execution() 表示拦截方法;
第一个* 表示方法的返回值是任意类型;
第二个* 表示匹配该类中的所有方法;
(..)表示方法的参数是任意类型的。
在Spring 中 XML 的配置文件如下(配置就是这么简单):
<!-- 自动扫描注解 -->
<context:component-scan base-package="com.xxx.*" />
<!-- 开启切面编程(通过配置织入@Aspectj切面 ) -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
Spring + AspectJ(基于注解:通过AspectJ @annotation 表达式拦截方法)
为了拦截指定的注解的方法,我们首先需要来定义一个注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodLog {
}
将之前的Aspect类的切点表达式稍作一下改动:
@Aspect
@Component
public class GreetingAspect {
@Around("@annotation(aop.demo.MethodLog)")
public Object arount(ProceedingJoinPoint pjp) throws Throwable{
before();
Object obj = pjp.proceed();
after();
return obj;
}
private void after() {
System.out.println("before advice");
}
private void before() {
System.out.println("after advice");
}
}
这次使用了@annotation() 表达式,需要要在括号内定义需要拦截的注解名称即可。直接将MethodLog注解定义在需要拦截的方法上,就是这么简单。
@Component
public class GreetingImpl {
@MehtodLog
public void sayHello(){
System.out.println("hello java");
}
}
这里只有一个方法,如果有多个方法,我们只想拦截其中的某一个时,这种解决方法会很好。
Spring + AspectJ(引入增强)
为了实现基于AspectJ 的引入增强,我们同样需要定义一个Aspect 类:
@Aspect
@Component
public class GreetingAspect {
@DeclareParents(value="aop.demo.GreetingImpl", defaultImpl = ApologyImpl.class)
private Apology Apology;
}
在Aspect 类中定义一个需要引入增强的接口,它就是运行时需要动态实现的接口。在这个接口上标注了DeclareParents注解,该注解有两个属性:
value ---目标类;
defaultImpl ---引入接口的默认实现类。
我们需要对引入的接口提供一个默认的实现类就可以完成引入的增强:
public class ApologyImpl implements Apology{
@Override
public void saySorry() {
System.out.println("我是增强类, 我说sorry");
}
}
以上这个实现hi在运行时自动增强到GreetingImpl类中,也就是说,无须修改GreetImpl类的代码,让它去实现Apology 接口,我们单独为该接口提供一个实现类(ApologyImpl)来做GreetingImpl 想做的事情。
测试代码:
ApplicationContext context = new FileSystemXmlApplicationContext("beans-config.xml");
Greeting proxy = (Greeting) context.getBean("greetimpl");
proxy.sayHello();
// 看来好像 Apology 物件动态增加了职责
((Apology) proxy).saySorry();
运行结果:
hello java
我是增强类, 我说sorry
Aspect其他注解介绍
Before ----- 前置增强;
After ----- 后置增强;
Around ----- 环绕增强;
AfterThrowing ----- 抛出增强;
DeclareParents ----- 引入增强。
Spring + AspectJ(基于配置)
使用AspectJ 的增强 比原来 的Spring AOP 增强很方便,这算是一个巨大的突破。但是任然有用户不能尝试这些特性,因为他们还在使用低于JDK 1.5 (没有注解)。spring 提供配置解决了这个问题。
<bean id="greetingImpl" class="aop.demo.GreetingImpl" />
<bean id="greetingAspect" class="aop.demo.GreetingAspect" />
<aop:config>
<aop:aspect ref="greetingAspect">
<aop:around method="around" pointcut="execution(* aop.demo.GreetingImpl.*(..))"/>
</aop:aspect>
</aop:config>
使用<aop:config> 元素来进行AOP 配置,在其子元素中配置切面,包括增强类型,目标方法,切点等信息。
总结
各类增强类型对于的解决方法:
增强类型 基于AOP 基于AOP注解 基于<aop:cofnig> 配置
BefooreAdvice(前置增强) MethodBeforeAdvice @Before <aop:before>
AfterAdvice(后置增强) AfterReturningAdIve @After <aop:after>
AroundAdvice(环绕增强) MethodInterceptor @Around <aop:around>
ThrowsAdvice(异常增强) ThrowsAdvice @AfterThrowing <aop:after-throwing>
IntroductionAdvice(引入增强) DelegatingIntroductionInteceptor @DeclareParents <aop:declare-parents>
Spring AOP 的整体架构
spring---aop(10)---Spring AOP中AspectJ的更多相关文章
- 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制
spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...
- 10 Spring框架 AOP (三) Spring对AspectJ的整合
上两节我们讲了Spring对AOP的实现,但是在我们的开发中我们不太使用Spring自身的对AOP的实现,而是使用AspectJ,AspectJ是一个面向切面的框架,它扩展了Java语言.Aspect ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
- 【spring 5】AOP:spring中对于AOP的的实现
在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现. 一.采用Annotation方式 首先引入jar包:aspectjrt.jar && ...
- SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP
AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...
- spring aop方式配置事务中的三个概念 pointcut advice advisor
AOP的3个关键概念 因为AOP的概念难于理解,所以在前面首先对Java动态代理机制进行了一下讲解,从而使读者能够循序渐进地来理解AOP的思想. 学习AOP,关键在于理解AOP的思想,能够使用AOP. ...
- 10.Spring——框架的AOP
1.Spring 框架的 AOP 2.Spring 中基于 AOP 的 XML架构 3.Spring 中基于 AOP 的 @AspectJ 1.Spring 框架的 AOP Spring 框架的一个关 ...
- AOP 与 Spring中AOP使用(上)
AOP简介 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程, 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP是OOP的延续 ...
- JavaWeb_(Spring框架)认识Spring中的aop
1.aop思想介绍(面向切面编程):将纵向重复代码,横向抽取解决,简称:横切 2.Spring中的aop:无需我们自己写动态代理的代码,spring可以将容器中管理对象生成动态代理对象,前提是我们对他 ...
随机推荐
- java 证书体系及应用,自已做https证书
原文: https://blog.csdn.net/wjq008/article/details/49071857 接下来我们将域名www.zlex.org定位到本机上.打开C:\Windows\Sy ...
- 洛谷P2024食物链
传送门啦 这道题的特殊之处在于对于任意一个并查集,只要告诉你某个节点的物种,你就可以知道所有节点对应的物种. 比如一条长为4的链 甲->乙->丙->丁 ,我们知道乙是A物种.那么甲一 ...
- 使用JS实现文字搬运工
使用JS实现文字搬运工 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html><head><meta http-equiv=&quo ...
- elasticsearch5.5-head
修改 elasticsearch/config/elasticsearch.yml 添加 http.cors.enabled: true http.cors.allow-origin: "* ...
- CCF CSP 201503-3 节日
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201503-3 节日 问题描述 有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形 ...
- 转:40个Java集合面试问题和答案
转自牛客网:http://mp.weixin.qq.com/s?__biz=MjM5NDYxMzk1Nw==&mid=215319390&idx=1&sn=1ab621bc40 ...
- day1作业:编写登录窗口一个文件实现
思路: 1.参考模型,这个作业我参考了linux的登录认证流程以及结合网上银行支付宝等锁定规则: 1)认证流程参考的是Linux的登录:当你输入完用户名密码后再验证用户名是否存在用户是否被锁定,然后在 ...
- Kaldi 安装
以后要重点搞caldi了,虽然集群上有,但还是本地安装一下吧. 参考 Kaldi 学习手记(一):Kaldi 的编译安装 在 ubuntu 下安装 kaldi 基本步骤 两个文章基本差不多 1 ...
- vue.js 是如何做到数据响应的
许多前端JavaScript框架(例如Angular,React和Vue)都有自己的数据相应引擎.通过了解相应性及其工作原理,您可以提高开发技能并更有效地使用JavaScript框架.在视频和下面的文 ...
- JAVAEE——宜立方商城04:图片服务器FastDFS、富文本编辑器KindEditor、商品添加功能完成
1. 学习计划 1.图片上传 a) 图片服务器FastDFS b) 图片上传功能实现 2.富文本编辑器的使用KindEditor 3.商品添加功能完成 2. 图片服务器的安装 1.存储空间可扩展. 2 ...