Spring Aop(十六)——编程式的自定义Advisor
转发:https://www.iteye.com/blog/elim-2399437
https://www.iteye.com/blogs/subjects/springaop
编程式的自定义Advisor
概述
大多数情况下,我们的Aop应用都可以通过Spring的Aop配置来进行(不管是基于注解的,还是基于XML配置的)。Spring Aop的核心就是Advisor,Advisor接口中暂时有用的就是getAdvice()方法,而isPerInstance()方法官方说暂时还没有应用到,生成的Advisor是单例还是多例不由isPerInstance()的返回结果决定,而由自己在定义bean的时候控制。
public interface Advisor {
Advice getAdvice();
boolean isPerInstance();
}
我们在使用Advisor时不会直接实现Advisor的接口,而是实现Advisor接口的子接口,PointcutAdvisor或IntroductionAdvisor。IntroductionAdvisor个人感觉用处不大,我们之前介绍的@DeclareParents和<aop:declare-parents/>就属于IntroductionAdvisor使用,它们对应的是DeclareParentsAdvisor。剩下的大部分应用的都是PointcutAdvisor。PointcutAdvisor接口的定义如下。
public interface PointcutAdvisor extends Advisor {
Pointcut getPointcut();
}
我们可以看到它在Advisor接口的基础上新增了一个getPointcut()方法,用以指定我们的Advisor需要应用到哪些Pointcut,即哪些方法调用。编程式的Pointcut定义之前已经介绍过了,它不属于本文介绍的范畴,这里就不再赘述了,对这块不是很了解的读者建议从头看起,笔者的博文是系列博文,当然了也可以暂时先略过,直接看笔者下文的示例。
实现自定义的Advisor
以下是笔者实现的一个自定义的Advisor,是实现的PointcutAdvisor接口。应用的Advice是MethodBeforeAdvice的实现;应用的Pointcut简单匹配所有类的方法名为find的方法调用。
public class MyAdvisor implements PointcutAdvisor {
@Override
public Advice getAdvice() {
return new MethodBeforeAdvice() {
@Override
public void before(Method method,
Object[] args, Object target) throws Throwable {
System.out.println("BeforeAdvice实现,在目标方法被调用前调用,目标方法是:"
+ method.getDeclaringClass().getName() + "."
+ method.getName());
}
};
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public Pointcut getPointcut() {
/**
* 简单的Pointcut定义,匹配所有类的find方法调用。
*/
return new Pointcut() {
@Override
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}
@Override
public MethodMatcher getMethodMatcher() {
return new MethodMatcher() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
String methodName = method.getName();
if ("find".equals(methodName)) {
return true;
}
return false;
}
@Override
public boolean isRuntime() {
return false;
}
@Override
public boolean matches(Method method, Class<?> targetClass,
Object[] args) {
return false;
}
};
}
};
}
}
配置使用自定义的Advisor
有了自定义的Advisor后我们应该如何来应用它呢?这又区分好几种情况。
- 如果是自己通过编程应用
ProxyFactory,或者说是应用ProxyCreatorSupport来创建代理对象,那么我们通过AdvisedSupport.addAdvisor(Advisor advisor)来应用我们自定义的Advisor。AdvisedSupport的子类中有ProxyCreatorSupport。 - 如果我们的项目中已经应用了
<aop:aspectj-autoproxy/>或<aop:config>,那么我们定义在bean容器中的Advisorbean会自动应用到匹配的bean上。这个在《Spring Aop原理之自动创建代理对象》一文中有详细介绍。 - 如果项目中没有应用
<aop:aspectj-autoproxy/>或<aop:config>,我们就需要自己定义BeanNameAutoProxyCreator、DefaultAdvisorAutoProxyCreator等AbstractAdvisorAutoProxyCreator类型的bean了。或者是定义AnnotationAwareAspectjAutoProxyCreator或AspectJAwareAdvisorAutoProxyCreator类型的bean,其实<aop:aspectj-autoproxy/>就是自动定义了AnnotationAwareAspectjAutoProxyCreator类型的bean,<aop:config>就是自动定义了AspectJAwareAdvisorAutoProxyCreator类型的bean。这样在创建bean后都会寻找匹配的Advisor建立对应的代理对象。这些都在《Spring Aop原理之自动创建代理对象》一文中有详细介绍,细节这里就不再赘述。
(注:本文是基于Spring4.1.0所写,写于2017年5月16日)
Spring Aop(十六)——编程式的自定义Advisor的更多相关文章
- Spring Boot(十六):使用Jenkins部署Spring Boot
Spring Boot(十六):使用Jenkins部署Spring Boot jenkins是devops神器,介绍如何安装和使用jenkins部署Spring Boot项目 jenkins搭建 部署 ...
- Spring Aop(十)——编程式的Pointcut
转发地址:https://www.iteye.com/blog/elim-2396526 编程式的Pointcut 除了可以通过注解和Xml配置定义Pointcut之外,其实我们还可以通过程序来定义P ...
- Spring学习(十六)----- Spring AOP实例(Pointcut(切点),Advisor)
在上一个Spring AOP通知的例子,一个类的整个方法被自动拦截.但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因.它允许你通过它的方法名来拦截方法.另外, ...
- Spring框架——事务处理(编程式和声明式)
一. 事务概述 ●在JavaEE企业级开发的应用领域,为了保证数据的完整性和一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术. ●事务就是一组由于逻辑上紧密关联而合 ...
- Spring事务管理之编程式事务管理
© 版权声明:本文为博主原创文章,转载请注明出处 案例:利用Spring的编程式事务管理模拟转账过程 数据库准备 -- 创建表 CREATE TABLE `account`( `id` INT NOT ...
- Spring Aop(六)——@DeclareParents介绍
转发:https://www.iteye.com/blog/elim-2395410 6 @DeclareParents介绍 @DeclareParents注解也是Aspectj提供的,在使用基于As ...
- Spring MVC(十六)--Spring MVC国际化实例
上一篇文章总结了一下Spring MVC中实现国际化所需的配置,本文继上一文举一个完整的例子,我选择用XML的方式.我的场景是这样的: 访问一个页面时,这个页面有个表格,对表头中的列名实现国际化. 第 ...
- (转)Spring Boot(十六):使用 Jenkins 部署 Spring Boot
http://www.ityouknow.com/springboot/2017/11/11/spring-boot-jenkins.html enkins 是 Devops 神器,本篇文章介绍如何安 ...
- Spring Boot(十六):使用 Jenkins 部署 Spring Boot
Jenkins 是 Devops 神器,本篇文章介绍如何安装和使用 Jenkins 部署 Spring Boot 项目 Jenkins 搭建.部署分为四个步骤: 第一步,Jenkins 安装 第二步, ...
随机推荐
- ubuntu下新立得(synaptic)软件包管理器安装
1.从ubuntu下的软件中心(面板主页中输入soft即可找到)搜索安装synaptic后,打开新立得一闪就自动关了.解决办法为: 1.1命令行下卸载,命令行下重新安装: 卸载: #purge表示卸载 ...
- input 限制输入数字和小数
//input 限制输入数字和小数 <input type="text" name="demo" value="" onkeyup=& ...
- [Angular 8] Calculate and Measure Performance budgets with the Angular CLI
Measuring is extremely important, without numbers we don’t know about potential problems and we don’ ...
- bootstrap富文本编辑
先把设定富文本框架 <div class="form-group"> <label class="col-sm-2 control-label" ...
- bzoj 1396/2865: 识别子串 后缀自动机+线段树
水水的字符串题 ~ #include <map> #include <cstdio> #include <cstring> #include <algorit ...
- 数据结构实验之查找四:二分查找(SDUT 3376)
#include <stdio.h> #include <string.h> #include <stdlib.h> int a[1000005]; int fin ...
- 遇到bug如何处理
issue中查询是否有相似bug assert / try-except / IDE单步调式 框架可以查询源码或者查询官方文档
- C# 下划线转驼峰
/// <summary> /// 转换 /// </summary> /// <param name="sender"></param& ...
- Linux 如何通过某一台服务器调用执行多台远程服务器上的脚本,结果显示在本地?
现在都流行自动化运维了,可能目前技术不够,很多自动化工具还不怎么会用,所以本次只是通过ssh来实现功能. 说明:自己写的一个简单脚本,只是实现了基础功能,还有待优化. 一共三台机器: master:1 ...
- CF1188B Count Pairs
[题目描述] 给定一个质数 \(p\) , 一个长度为 \(n\)n 的序列 \(a = \{ a_1,a_2,\cdots,a_n\}\)一个整数 \(k\). 求所有数对 \((i, j)\) ( ...