转发: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. Nutch2.1+mysql+solr3.6.1+中文网站抓取

    1.mysql 数据库配置 linux mysql安装步骤省略. 在首先进入/etc/my.cnf (mysql为5.1的话就不用修改my.cnf,会导致mysql不能启动)在[mysqld] 下添加 ...

  2. Linux Soft-RoCE implementation (zz)

    Linux Soft-RoCE implementation 首页分类标签留言关于订阅2017-11-08 | 分类 Network  | 标签 RDMA  RoCE  Linux-RDMA 内核在4 ...

  3. 【SPOJ】Longest Common Substring

    [SPOJ]Longest Common Substring 求两个字符串的最长公共子串 对一个串建好后缀自动机然后暴力跑一下 废话 讲一下怎么跑吧 从第一个字符开始遍历,遍历不到了再沿着\(pare ...

  4. elasticsearch集群健康状态查看

    1. 查看ES集群健康状态 http://localhost:9200/_cluster/health?pretty 响应: { "cluster_name" : "if ...

  5. 编程微语 2019-Autumn

    很多时候我们要的是[网页全屏],可是许多软件却做成了[浏览器全屏],不要一听到[全屏]就认为真的是传统意义上的全屏.拜托,老板(往往就是最大的产品经理).产品经理.程序员,想想,说清楚,做正确.某度文 ...

  6. Kafka 最新版配置

    当前基于kafaka最新版 kafka_2.12-2.2.1.tgz 进行配置 . 官网地址:http://kafka.apache.org/intro kafka的一些基础知识 参考:http:// ...

  7. 通过AS提交AndroidLibrary到JCenter仓库

    注意事项: //版本需要一致,如下版本对应gradle-4.4-all.zip dependencies { classpath 'com.android.tools.build:gradle:3.1 ...

  8. Oracle sql 复习题目总结

    sql 题目一 表结构 1.表名:g_cardapply 字段(字段名/类型/长度): apply_no varchar8; //申请单号(关键字) apply_date date; //申请日期 s ...

  9. WebSocketSharp 创建客户端和服务端

    这里没有对onOpen.onClose.onError做案例,生产环境需要具备. 1.客户端 只推送不接收数据 创建WebSocketClient类 class WebSocketClient { W ...

  10. Flutter移动电商实战 --(43)详细页_补充首页跳转到详细页

    首页轮播点击到详细页 修改我们轮播这里的代码:SwiperDiy这个类这里的代码 return InkWell( onTap: (){ Application.router.navigateTo(co ...