Spring AOP APIs
一)一个最简单的例子
public interface MessageSender {
void send(String message);
}
public class HttpMessageSender implements MessageSender {
public void send(String message) {
System.out.println("Send Message[" + message + "] by http.");
}
}
public class LogBeforeAdvice implements MethodAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("Log before " + method + " by LogBeforeAdvice.");
}
}
<bean id="messageSenderImpl" class="com.savage.aop.HttpMessageSender"></bean>
<bean id="logBeforeAdvice" class="com.savage.aop.LogBeforeAdvice"></bean>
<bean id="messageSender" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="com.savage.aop.MessageSender"/>
<property name="target" ref="messageSenderImpl"/>
<property name="interceptorNames">
<list>
<value>logBeforeAdvice</value>
</list>
</property>
</bean>
这样我们就为MessageSender对象指定了一个Before Advice。
在这里,我们分别定义了一个HttpMessageSender的bean(messageSenderImpl),一个Before Advice的bean(logBeforeAdvice)和一个org.springframework.aop.framework.ProxyFactoryBean的bean (messageSender)。
FactoryBean或ApplicationContext将使用ProxyFactoryBean来建立代理对象,在这里就是建立messageSenderImpl的代理对象。在ProxyFactoryBean的定义中,proxyInterfaces属性指定了要代理的接口;target指定了要建立代理的目标对象;interceptorNames则指定了应用与指定接口上的Advices对象列表,spring将根据列表中定义的顺序在执行目标对象的方法前、后执行。
二)AOP的Adivce
先说说adivce,可以分为Per-class和Per-instance。
Per-class是指类级别的adivce,及该类的每个实例都相同的切面。切面不会为目标对象保存任何状态或者添加新的特性。 Before Advice,Throws Advice,After Returning Advice,Around Advice都属于这个类。
Per-instance是指为每个实例各自保存状态或者添加新特性的advice。Introduction就属于这一类。
Before Advice对应的接口是MethodBeforeAdvice
Throws Advice对应的接口是ThrowsAdvice
After Returning Advice对应的接口是AfterReturningAdvice
Around Advice对应的接口是MethodInterceptor
Introduction对应的接口是IntroductionInterceptor
不同的Adivce的使用方式都基本一致。参照样例在interceptorNames属性中加入需要使用的一个或多个Adivce的bean id即可。
三)AOP的Pointcut
Pointcut的核心接口是:
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
其中,ClassFilter和MethodMather分别用于匹配将被执行织入操作的对象以及相应的方法。
先说说ClassFilter。它的作用是对jointpoint处的对象进行class级别的匹配。
public interface ClassFilter {
boolean matches(Class clazz);
}
当织入的目标对象的class类型与pointcut所规定的类型相符时,matches方法将返回true。否则将返回false,即意味着不会对这个类型进行织入操作。
再来说说MethodMatcher。
public interface MethodMatcher {
boolean matches(Method m, Class targetClass);
boolean isRuntime();
boolean matches(Method m, Class targetClass, Object[] args);
}
MethodMatcher定义了2个matches的方法。在对对象方法进行具体拦截的时候,可以忽略每次方法执行的时候调用者传入的参数,也可以每次都检查这些方法调用参数,以强化拦截条件。
1)前者我们调用matches(Method m, Class targetClass); 而后isRuntime();返回false,表示检查结束。这种类型的MethodMatcher称为静态方法匹配。
2)后者在isRuntime();返回true时进而调用matches(Method m, Class targetClass, Object[] args);做更严格的参数匹配。这种类型的MethodMathcer称为动态方法匹配。显然,这种类型虽然严格但性能较差。
通过以上3个接口,我们就能灵活的自定义我们需要的Pointcut类型。但强大的Spring已经预定义好了足够的pointcut。大多数情况我们只需直接调用那些预留的pointcut即可满足需求了。比如 JdkRegexpMethodPointcut ControlFlowPointcut等等。
最后一点需要注意的是,就像例子中展示的那样,pointcut一般不在配置文件中显示的注入(当然你可以这样配置,这并不违反spring的原则),而是一个隐藏在幕后的英雄。
四)AOP的Aspect
AOP API中的Aspect叫做Advisor.而与一般的一个Aspect可以对应多个pointcut和advice不同。一个Advisor只能对应一个advice和一个pointcut。
同样的,spring也已经提供了许多的预定义的Advisor.一般情况下,已经不需要我们去自定义了。而这些预定义好的Advisor大致可以分成两类:PointcutAdvisor 和 IntroductionAdvisor。
DefaultPointcutAdvisor是最通用的Advisor实现。除了不能为其指定Introduction类型的Advice之外。其它所有的Advice和Pointcut都可以通过DefaultPointcutAdvisor来使用。
五)AOP的织入
就如上面的例子所示,由ProxyFactory类负责织入。由代码织入的例子如下:
ProxyFactory weaver = new ProxyFactory(yourTargetObject);
Advisor advisor = ...;
weaver.addAdvisor(advisor );
Object proxyObject = weaver.getProxy();
//现在你可以使用proxyObject了
当然,你还可以调用weaver.addAdvice(...);直接指定各种类型的Advice。
分享到:
相关推荐
6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1....
3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................
3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................
IV. 授权 13. 验证架构 13.1. 验证 13.2. 处理预调用 13.2.1. AccessDecisionManager 13.2.2. 基于投票的AccessDecisionManager实现 13.2.2.1. RoleVoter 13.2.2.2. AuthenticatedVoter 13.2.2.3. Custom ...
3.1 AOP及Spring AOP基础 3.1.1 细说AOP 3.1.2 Spring AOP基础概念 3.2 AspectJ 6初探 3.3 老式Spring AOP 3.4 基于@AspectJ的Spring AOP 3.5 基于<aop:config/>元素的AOP 3.5.1 巧用<aop:include/>元素 3.6 在...
6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 ...
6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.6.1. 理解AOP代理 6.7. 以编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ进行domain ...
6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个...
6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点...
Spring框架通过提供依赖注入、面向切面编程(AOP)等功能,简化了复杂性并增强了可维护性。而Hadoop框架,作为大数据处理的基石,为分布式存储和处理提供了基础。 II. 大数据与Spring框架的结合 Spring框架与...
2. **Spring框架**:在企业级Java应用中,Spring框架非常常见,用于依赖注入、AOP(面向切面编程)和Web开发。IV期可能涉及Spring Boot的微服务架构调整,或者使用Spring Data来优化数据库访问。 3. **并发与多线程...
Spring作为核心框架,负责依赖注入(DI)和面向切面编程(AOP),SpringMVC是Spring的一个模块,处理Web请求,而MyBatis则作为持久层框架,用于操作数据库。MySQL是一种高效、稳定的关系型数据库管理系统,适合存储大量...
AOP操作日志默认已使用Elasticseach全文检索引擎记录,使用Spring Data Elasticsearch简化开发 为什么要前后端分离 都什么时代了还在用JQuery? 分支说明 master:基于Redis的‘JWT’ (待提交) jwt:基于JWT,由于...
后端部分,文件包括"DecodeRequestBodyAdvice.java"和"EncodeResponseBodyAdvice.java",这些通常是Spring框架中的AOP(面向切面编程)拦截器,用于在请求到达控制器之前解密请求体,并在响应发送回客户端之前加密...