编程式的自定义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容器中的Advisor
bean会自动应用到匹配的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日)
相关推荐
在Java世界中,Spring框架是不可或缺的一部分,它以其强大的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)特性,极大地简化了企业级应用的开发。ApplicationContext是...
《Spring IOC源码解析(一)——整体介绍》 在深入理解Spring框架的过程中,源码分析是不可或缺的一环。本文将对Spring的IOC(Inversion of Control,控制反转)容器的源码进行初步探讨,旨在帮助读者从整体上把握...
源码分析将解释AspectJ、Proxy模式以及自定义Advisor和Pointcut的实现细节。 另外,Spring的DI机制也是关键部分。通过XML、注解或编程式方式,开发者可以声明Bean之间的依赖关系。源码解析会涵盖构造器注入、setter...
8. **AOP 代理**:Spring 使用两种代理模式——JDK 动态代理和 CGLIB 代理,根据目标类是否实现了接口来选择。源码中,`AbstractAutoProxyCreator` 负责创建代理对象。 9. **事件驱动架构**:Spring 支持事件发布和...
《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...
Spring框架中的AOP(面向方面编程)是其核心特性之一,它是对传统面向对象编程(OOP)的一种补充,用于解决横切关注点的问题,即那些在多个类中重复出现的非核心业务逻辑,如事务管理、日志记录、安全性等。AOP将...
《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...
其次,AOP是Spring提供的一种强大的模块,允许我们在不修改代码的情况下对横切关注点进行编程,如日志记录、性能监控等。源码中,`AspectJ`相关的类和`Advice`、`Pointcut`、`Advisor`等概念将帮助我们理解AOP的工作...
作为一款轻量级的Java平台框架,Spring提供了广泛的解决方案,从基础的依赖注入(DI)到复杂的事务管理和面向切面编程(AOP),几乎涵盖了企业级应用的各个方面。 - **核心特性**包括依赖注入、面向切面编程、数据...
《Spring配置文件详解——共五页》 在Java开发领域,Spring框架无疑是最为重要的工具之一,它以其强大的依赖注入和面向切面编程能力,极大地简化了企业级应用的开发。本篇文档将深入探讨Spring配置文件的核心概念,...