转发:https://www.iteye.com/blog/elim-2399437

https://www.iteye.com/blogs/subjects/springaop

编程式的自定义Advisor

概述

大多数情况下,我们的Aop应用都可以通过Spring的Aop配置来进行(不管是基于注解的,还是基于XML配置的)。Spring Aop的核心就是AdvisorAdvisor接口中暂时有用的就是getAdvice()方法,而isPerInstance()方法官方说暂时还没有应用到,生成的Advisor是单例还是多例不由isPerInstance()的返回结果决定,而由自己在定义bean的时候控制。

public interface Advisor {

	Advice getAdvice();

	boolean isPerInstance();

}

我们在使用Advisor时不会直接实现Advisor的接口,而是实现Advisor接口的子接口,PointcutAdvisorIntroductionAdvisorIntroductionAdvisor个人感觉用处不大,我们之前介绍的@DeclareParents<aop:declare-parents/>就属于IntroductionAdvisor使用,它们对应的是DeclareParentsAdvisor。剩下的大部分应用的都是PointcutAdvisorPointcutAdvisor接口的定义如下。

public interface PointcutAdvisor extends Advisor {

	Pointcut getPointcut();

}

我们可以看到它在Advisor接口的基础上新增了一个getPointcut()方法,用以指定我们的Advisor需要应用到哪些Pointcut,即哪些方法调用。编程式的Pointcut定义之前已经介绍过了,它不属于本文介绍的范畴,这里就不再赘述了,对这块不是很了解的读者建议从头看起,笔者的博文是系列博文,当然了也可以暂时先略过,直接看笔者下文的示例。

实现自定义的Advisor

以下是笔者实现的一个自定义的Advisor,是实现的PointcutAdvisor接口。应用的AdviceMethodBeforeAdvice的实现;应用的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)来应用我们自定义的AdvisorAdvisedSupport的子类中有ProxyCreatorSupport
  • 如果我们的项目中已经应用了<aop:aspectj-autoproxy/><aop:config>,那么我们定义在bean容器中的Advisor bean会自动应用到匹配的bean上。这个在《Spring Aop原理之自动创建代理对象》一文中有详细介绍。
  • 如果项目中没有应用<aop:aspectj-autoproxy/><aop:config>,我们就需要自己定义BeanNameAutoProxyCreatorDefaultAdvisorAutoProxyCreatorAbstractAdvisorAutoProxyCreator类型的bean了。或者是定义AnnotationAwareAspectjAutoProxyCreatorAspectJAwareAdvisorAutoProxyCreator类型的bean,其实<aop:aspectj-autoproxy/>就是自动定义了AnnotationAwareAspectjAutoProxyCreator类型的bean,<aop:config>就是自动定义了AspectJAwareAdvisorAutoProxyCreator类型的bean。这样在创建bean后都会寻找匹配的Advisor建立对应的代理对象。这些都在《Spring Aop原理之自动创建代理对象》一文中有详细介绍,细节这里就不再赘述。

(注:本文是基于Spring4.1.0所写,写于2017年5月16日)

Spring Aop(十六)——编程式的自定义Advisor的更多相关文章

  1. Spring Boot(十六):使用Jenkins部署Spring Boot

    Spring Boot(十六):使用Jenkins部署Spring Boot jenkins是devops神器,介绍如何安装和使用jenkins部署Spring Boot项目 jenkins搭建 部署 ...

  2. Spring Aop(十)——编程式的Pointcut

    转发地址:https://www.iteye.com/blog/elim-2396526 编程式的Pointcut 除了可以通过注解和Xml配置定义Pointcut之外,其实我们还可以通过程序来定义P ...

  3. Spring学习(十六)----- Spring AOP实例(Pointcut(切点),Advisor)

    在上一个Spring AOP通知的例子,一个类的整个方法被自动拦截.但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因.它允许你通过它的方法名来拦截方法.另外, ...

  4. Spring框架——事务处理(编程式和声明式)

     一. 事务概述 ●在JavaEE企业级开发的应用领域,为了保证数据的完整性和一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术. ●事务就是一组由于逻辑上紧密关联而合 ...

  5. Spring事务管理之编程式事务管理

    © 版权声明:本文为博主原创文章,转载请注明出处 案例:利用Spring的编程式事务管理模拟转账过程 数据库准备 -- 创建表 CREATE TABLE `account`( `id` INT NOT ...

  6. Spring Aop(六)——@DeclareParents介绍

    转发:https://www.iteye.com/blog/elim-2395410 6 @DeclareParents介绍 @DeclareParents注解也是Aspectj提供的,在使用基于As ...

  7. Spring MVC(十六)--Spring MVC国际化实例

    上一篇文章总结了一下Spring MVC中实现国际化所需的配置,本文继上一文举一个完整的例子,我选择用XML的方式.我的场景是这样的: 访问一个页面时,这个页面有个表格,对表头中的列名实现国际化. 第 ...

  8. (转)Spring Boot(十六):使用 Jenkins 部署 Spring Boot

    http://www.ityouknow.com/springboot/2017/11/11/spring-boot-jenkins.html enkins 是 Devops 神器,本篇文章介绍如何安 ...

  9. Spring Boot(十六):使用 Jenkins 部署 Spring Boot

    Jenkins 是 Devops 神器,本篇文章介绍如何安装和使用 Jenkins 部署 Spring Boot 项目 Jenkins 搭建.部署分为四个步骤: 第一步,Jenkins 安装 第二步, ...

随机推荐

  1. Tornado之Session实现

    Tornado框架中,默认执行Handler的get/post等方法之前默认会执行 initialize方法,所以可以通过自定义的方式使得所有请求在处理前执行操作 import tornado.iol ...

  2. 聊聊rocketmq的sendBatchMessage

    序 本文主要研究一下rocketmq的sendBatchMessage SendMessageRequestHeader rocketmq-all-4.6.0-source-release/commo ...

  3. NuGet本地包自定义路径

    <?xml version="1.0" encoding="utf-8"?> <configuration> <packageSo ...

  4. 学到了林海峰,武沛齐讲的Day17完-6 文件操作

    参考   https://www.cnblogs.com/linhaifeng/articles/5984922.html f=open('陈粒1',encoding='utf-8')     ope ...

  5. AcWing P173 矩阵距离 题解

    Analysis 就是一个裸的广搜,每次从是1的点开始找就好啦~~~ #include<iostream> #include<cstdio> #include<cstri ...

  6. 页面打开excel

    1. File => Stream / MemoryStream FileStream stream = new FileStream(path, FileMode.Open, FileAcce ...

  7. java重载和重写

    重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. ...

  8. About & Ideas & Queries

    About Blog主现高一,文化课和OI啥都不会 本Blog主太懒,所以很多内容都缩在一个文章里,如数学.图论大礼包 https://wenku.baidu.com/view/56d76029647 ...

  9. Python中一些高效的数据操作

    列表统计 chars = ["a", "b", "a", "c", "a", "d&quo ...

  10. Python基础之定义有默认参数的函数

    1. 构建有默认参数的函数 当我们在构建一个函数或者方法时,如果想使函数中的一个或者多个参数使可选的,并且有一个默认值,那么可以在函数定义中给参数指定一个默认值,并且放到参数列表的最后就行了.比如: ...