spring源代码解析(七):spring AOP中对拦截器调用的实现
前面我们分析了Spring AOP实现中得到Proxy对象的过程,下面我们看看在Spring AOP中拦截器链是怎样被调用的,也就是Proxy模式是怎样起作用的,或者说Spring是怎样为我们提供AOP功能的;在JdkDynamicAopProxy中生成Proxy对象的时候:Java代码1.return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);这里的this参数对应的是InvocationHandler对象,这里我们的JdkDynamicAopProxy实现了这个接口,也就是说当Proxy对象的函数被调用的时候,这个InvocationHandler的invoke方法会被作为回调函数调用,下面我们看看这个方法的实现:Java代码1.public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {2. MethodInvocation invocation = null;3. Object oldProxy = null;4. boolean setProxyContext = false;5.6. TargetSource targetSource = this.advised.targetSource;7. Class targetClass = null;8. Object target = null;9.10. try {11. // Try special rules for equals() method and implementation of the12. // Advised AOP configuration interface.13.14. if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {15. // What if equals throws exception!?16. // This class implements the equals(Object) methoditself.17. return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE;18. }19. if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {20. // This class implements the hashCode() method itself.21. return new Integer(hashCode());22. }23. if (Advised.class == method.getDeclaringClass()) {24. // service invocations on ProxyConfig with the proxy config25. return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);26. }27.28. Object retVal = null;29.30. if (this.advised.exposeProxy) {31. // make invocation available if necessary32. oldProxy = AopContext.setCurrentProxy(proxy);33. setProxyContext = true;34. }35.36. // May be <code>null</code>. Get as late as possible tominimize the time we "own" the target,37. // in case it comes from a pool.38. // 这里是得到目标对象的地方,当然这个目标对象可能来自于一个实例池或者是一个简单的JAVA对象39. target = targetSource.getTarget();40. if (target != null) {41. targetClass = target.getClass();42. }43.44. // get the interception chain for this method45. // 这里获得定义好的拦截器链46. List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(47. this.advised, proxy, method, targetClass);48.49. // Check whether we have any advice. If we don't, we can fallback on direct50. // reflective invocation of the target, and avoid creating a MethodInvocation.51. // 如果没有设定拦截器,那么我们就直接调用目标的对应方法52. if (chain.isEmpty()) {53. // We can skip creating a MethodInvocation: just invoke the target directly54. // Note that the final invoker must be an InvokerInterceptor so we know it does55. // nothing but a reflective operation on the target, and no hot swapping or fancy proxying56. retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);57. }58. else {59. // We need to create a method invocation...60. // invocation = advised.getMethodInvocationFactory().getMethodInvocation(61. // proxy, method, targetClass, target, args, chain, advised);62. // 如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相应方法63. // 这里通过构造一个ReflectiveMethodInvocation来实现,下面我们会看这个ReflectiveMethodInvocation类64. invocation = new ReflectiveMethodInvocation(65. proxy, target, method, args, targetClass, chain);66.67. // proceed to the joinpoint through the interceptorchain68. // 这里通过ReflectiveMethodInvocation来调用拦截器链和相应的目标方法69. retVal = invocation.proceed();70. }71.72. // massage return value if necessary73. if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) {74. // Special case: it returned "this" and the returntype of the method is type-compatible75. // Note that we can't help if the target sets76. // a reference to itself in another returned object.77. retVal = proxy;78. }79. return retVal;80. }81. finally {82. if (target != null && !targetSource.isStatic()) {83. // must have come from TargetSource84. targetSource.releaseTarget(target);85. }86.87. if (setProxyContext) {88. // restore old proxy89. AopContext.setCurrentProxy(oldProxy);90. }91. }92.}我们先看看目标对象方法的调用,这里是通过AopUtils的方法调用 - 使用反射机制来对目标对象的方法进行调用:Java代码1.public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)2. throws Throwable {3.4. // Use reflection to invoke the method.5. // 利用放射机制得到相应的方法,并且调用invoke6. try {7. if (!Modifier.isPublic(method.getModifiers()) ||8. !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {9. method.setAccessible(true);10. }11. return method.invoke(target, args);12. }13. catch (InvocationTargetException ex) {14. // Invoked method threw a checked exception.15. // We must rethrow it. The client won't see the interceptor.16. throw ex.getTargetException();17. }18. catch (IllegalArgumentException ex) {19. throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +20. method + "] on target [" + target + "]", ex);21. }22. catch (IllegalAccessException ex) {23. throw new AopInvocationException("Couldn't access method: " + method, ex);24. }25.}对拦截器链的调用处理是在ReflectiveMethodInvocation里实现的:Java代码1.public Object proceed() throws Throwable {2. // We start with an index of -1 and increment early.3. // 这里直接调用目标对象的方法,没有拦截器的调用或者拦截器已经调用完了,这个currentInterceptorIndex的初始值是04. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()) {5. return invokeJoinpoint();6. }7.8. Object interceptorOrInterceptionAdvice =9. this.interceptorsAndDynamicMethodMatchers.get(this.currentInterceptorIndex);10. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {11. // Evaluate dynamic method matcher here: static part will already have12. // been evaluated and found to match.13. // 这里获得相应的拦截器,如果拦截器可以匹配的上的话,那就调用拦截器的invoke方法14. InterceptorAndDynamicMethodMatcher dm =15. (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;16. if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {17. return dm.interceptor.invoke(nextInvocation());18. }19. else {20. // Dynamic matching failed.21. // Skip this interceptor and invoke the next in thechain.22. // 如果拦截器匹配不上,那就调用下一个拦截器,这个时候拦截器链的位置指示后移并迭代调用当前的proceed方法23. this.currentInterceptorIndex++;24. return proceed();25. }26. }27. else {28. // It's an interceptor, so we just invoke it: The pointcut will have29. // been evaluated statically before this object was constructed.30. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(nextInvocation());31. }32.}这里把当前的拦截器链以及在拦截器链的位置标志都clone到一个MethodInvocation对象了,作用是当前的拦截器执行完之后,会继续沿着得到这个拦截器链执行下面的拦截行为,也就是会迭代的调用上面这个proceed:Java代码1.private ReflectiveMethodInvocation nextInvocation() throws CloneNotSupportedException {2. ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) clone();3. invocation.currentInterceptorIndex = this.currentInterceptorIndex + 1;4. invocation.parent = this;5. return invocation;6.}这里的nextInvocation就已经包含了当前的拦截链的基本信息,我们看到在Interceptor中的实现比如TransactionInterceptor的实现中:Java代码1.public Object invoke(final MethodInvocation invocation) throwsThrowable {2. ......//这里是TransactionInterceptor插入的事务处理代码,我们会在后面分析事务处理实现的时候进行分析3. try {4. //这里是对配置的拦截器链进行迭代处理的调用5. retVal = invocation.proceed();6. }7. ......//省略了和事务处理的异常处理代码,也是TransactionInterceptor插入的处理8. else {9. try {10. Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,11. new TransactionCallback() {12. public Object doInTransaction(TransactionStatus status) {13. //这里是TransactionInterceptor插入对事务处理的代码14. TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);15. //这里是对配置的拦截器链进行迭代处理的调用,接着顺着拦截器进行处理16. try {17. return invocation.proceed();18. }19. ......//省略了和事务处理的异常处理代码,也是TransactionInterceptor插入的处理20. }从上面的分析我们看到了Spring AOP的基本实现,比如Spring怎样得到Proxy,怎样利用JAVA Proxy以及反射机制对用户定义的拦截器链进行处理。
拦截器的实现原理
拦截器的实现原理拦截器是应用程序开发中常用的一种技术,用于在请求到达目标对象之前或者之后对请求进行处理或者操纵。
它是一种面向切面编程的实现方式,通过动态代理机制对请求进行拦截并进行相关的处理。
1. 动态代理机制:拦截器通常使用动态代理机制来实现对目标对象的拦截,它通过创建目标对象的代理对象并将请求转发给代理对象来实现拦截的效果。
动态代理可以分为两种方式,一种是基于接口的动态代理(JDK Proxy),另一种是基于类的动态代理(CGLIB)。
2. AOP和切面编程:拦截器使用AOP(Aspect Oriented Programming)和切面编程的思想来实现,将各种功能独立封装成切面,并通过拦截器来将切面应用于目标对象的方法调用。
切面是一个横切关注点的模块化单元,它可以包含任何功能,如事务管理、日志记录、性能监控等。
3.方法拦截:拦截器通过对目标对象的方法进行拦截实现请求的截获和处理。
拦截器可以在目标方法调用之前、之后或者异常发生时进行相关处理。
在方法调用之前,拦截器可以进行参数验证、权限检查等操作;在方法调用之后,拦截器可以进行结果处理、事务提交等操作;在方法发生异常时,拦截器可以进行异常处理、事务回滚等操作。
4.链式调用:拦截器的实现通常采用链式调用的方式,将多个拦截器串联起来形成一个拦截器链。
请求会按照拦截器链的顺序进行处理,每个拦截器都可以对请求进行拦截和处理。
如果一个拦截器放行了请求,后面的拦截器将会继续处理;如果拦截器中止了请求,后面的拦截器将不再执行。
5.反射机制:拦截器在对目标方法进行拦截时通常使用反射机制来调用目标方法。
通过反射,拦截器可以获取目标方法的参数、返回值等信息,并进行相应的处理。
同时,反射机制还可以在运行时动态修改方法的行为,实现拦截和操纵请求的效果。
综上所述,拦截器的实现原理主要包括动态代理、AOP和切面编程、方法拦截、链式调用和反射机制等方面。
拦截器通过动态代理机制创建代理对象,并通过对目标对象方法进行拦截和处理来实现对请求的拦截。
Java三大器之拦截器(Interceptor)的实现原理及代码示例
Java三⼤器之拦截器(Interceptor)的实现原理及代码⽰例1,拦截器的概念java⾥的拦截器是动态拦截Action调⽤的对象,它提供了⼀种机制可以使开发者在⼀个Action执⾏的前后执⾏⼀段代码,也可以在⼀个Action执⾏前阻⽌其执⾏,同时也提供了⼀种可以提取Action中可重⽤部分代码的⽅式。
在AOP中,拦截器⽤于在某个⽅法或者字段被访问之前,进⾏拦截然后再之前或者之后加⼊某些操作。
⽬前,我们需要掌握的主要是Spring的拦截器,Struts2的拦截器不⽤深究,知道即可。
2,拦截器的原理⼤部分时候,拦截器⽅法都是通过代理的⽅式来调⽤的。
Struts2的拦截器实现相对简单。
当请求到达Struts2的ServletDispatcher时,Struts2会查找配置⽂件,并根据配置实例化相对的拦截器对象,然后串成⼀个列表(List),最后⼀个⼀个的调⽤列表中的拦截器。
Struts2的拦截器是可插拔的,拦截器是AOP的⼀个实现。
Struts2拦截器栈就是将拦截器按⼀定的顺序连接成⼀条链。
在访问被拦截的⽅法或者字段时,Struts2拦截器链中的拦截器就会按照之前定义的顺序进⾏调⽤。
3,⾃定义拦截器的步骤第⼀步:⾃定义⼀个实现了Interceptor接⼝的类,或者继承抽象类AbstractInterceptor。
第⼆步:在配置⽂件中注册定义的拦截器。
第三步:在需要使⽤Action中引⽤上述定义的拦截器,为了⽅便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的Action都被这个拦截器拦截。
4,过滤器与拦截器的区别过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是⽅法调⽤,⽐如拦截敏感词汇。
4.1,拦截器是基于java反射机制来实现的,⽽过滤器是基于函数回调来实现的。
(有⼈说,拦截器是基于动态代理来实现的)4.2,拦截器不依赖servlet容器,过滤器依赖于servlet容器。
SpringAOP的原理和应用场景
SpringAOP的原理和应用场景SpringAOP(Aspect-Oriented Programming)是Spring框架中的一个重要组成部分,它提供了一种通过预定义的方式,将横切关注点(Cross-cutting Concerns)与业务逻辑进行解耦的机制。
本文将介绍SpringAOP的原理及其在实际应用场景中的应用。
一、SpringAOP的原理SpringAOP基于代理模式(Proxy Pattern)实现。
在SpringAOP中,通过生成与原始类(被代理类)具有相同接口的代理类,将横切逻辑编织到业务逻辑中。
在运行时,当调用代理类的方法时,会在方法执行前、后或异常抛出时插入相应的横切逻辑代码。
具体而言,SpringAOP使用了以下几个核心概念:1. 切面(Aspect):切面是横切逻辑的模块化单元,它包含了一组通知(Advice)和切点(Pointcut)。
2. 通知(Advice):通知定义了实际的横切逻辑代码,并规定了何时执行该代码。
SpringAOP提供了五种类型的通知:前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)。
3. 切点(Pointcut):切点指定了在哪些连接点(Join Point)上执行通知。
连接点可以是方法调用、属性访问等程序执行的点。
4. 连接点(Join Point):连接点是程序执行过程中的一个特定点,如方法调用前、方法调用后等。
通知通过切点来选择连接点。
5. 织入(Weaving):织入是将切面应用到目标对象,并创建代理对象的过程。
织入可以在编译时、类加载时或运行时进行。
二、SpringAOP的应用场景SpringAOP可应用于各种场景,用于解决跨越多个模块或类的横切关注点问题。
以下是一些常见的SpringAOP应用场景:1. 日志记录:通过在关键方法的前后插入日志代码,实现对系统运行状态的监控和记录。
AOP方法拦截获取参数上的注解
AOP⽅法拦截获取参数上的注解获取参数注解在spring aop中,⽆论是前置通知的参数JoinPoint,还是环绕通知的参数ProceedingJoinPoint,都可以通过以下⽅法获得⼊参: MethodSignature signature= (MethodSignature) jp.getSignature();根据源码分析,MethodSignature封装了两个⽅法,⼀个获取⽅法的返回值类型,⼀个是获取封装的Method对象,getReturnType()可以⽤在环绕通知中,我们可以根据这个class类型,做定制化操作.⽽method的参数和参数上的注解,就可以从getMethod()返回的Method对象中拿,api如下:// 获取⽅法上的注解XXX xxx = signature.getMethod().getAnnotation(XXX.class)//获取所有参数上的注解Annotation[][] parameterAnnotations= signature.getMethod().getParameterAnnotations();只有所有的参数注解怎么获取对应参数的值呢?获取所有参数注解返回的是⼀个⼆维数组Annotation[][],每个参数上可能有多个注解,是⼀个⼀维数组,多个参数⼜是⼀维数组,就组成了⼆维数组,所有我们在遍历的时候,第⼀次遍历拿到的数组下标就是⽅法参数的下标,for (Annotation[] parameterAnnotation: parameterAnnotations) {int paramIndex= ArrayUtils.indexOf(parameterAnnotations, parameterAnnotation);}再根据Object[] args= joinPoint.getArgs();拿到所有的参数,根据指定的下标即可拿到对象的值for (Annotation[] parameterAnnotation: parameterAnnotations) {int paramIndex= ArrayUtils.indexOf(parameterAnnotations, parameterAnnotation);for (Annotation annotation: parameterAnnotation) {if (annotation instanceof XXX){Object paramValue = args[paramIndex]}}}通过以上⽅法,即可找到你想要的参数注解,并拿到对应参数的值啦!。
Spring源码分析基本介绍
Spring源码分析基本介绍摘要:本⽂结合《Spring源码深度解析》来分析Spring 5.0.6版本的源代码。
若有描述错误之处,欢迎指正。
前⾔作为⼀名开发⼈员,阅读源码是⼀个很好的学习⽅式。
本⽂将结合《Spring源码深度解析》来分析Spring 5.0.6版本的源代码,若有描述错误之处,欢迎指正。
Spring是2003年兴起的⼀个轻量级Java开源框架,旨在解决企业应⽤开发的复杂性。
Spring发展⾄今,衍⽣出⾮常丰富的模块,并应⽤在多种场景,⽐如:桌⾯应⽤,Web应⽤等。
Spring的模块化可以允许你只使⽤需要的模块,⽽不必全部引⼊。
⽬录⼀、整体架构1. 核⼼容器2. 数据访问/集成3. Web4. AOP5. Test⼆、设计理念三、使⽤场景1. 典型的Spring web应⽤程序2. Spring中间层使⽤第三⽅web框架3. 远程调⽤4. EJBs-包装现存POJOs⼀、整体架构Spring框架是⼀个分层架构,他包含⼀系列的功能要素,并被分为⼤约20个模块,如下图所⽰(很遗憾,并没有找到Spring5的架构图,下图是Spring4的,但结合Spring5的源码来看,该图还是能够体现Spring5的核⼼模块)这些模块被总结为以下⼏部分。
1. 核⼼容器Core Container(核⼼容器)包含有Core、Beans、Context和Expression Language模块。
Core和Beans模块是框架的基础部分,提供IoC(控制反转)和DI(依赖注⼊)特性。
这⾥的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
Core模块主要包含Spring框架基本的核⼼⼯具类,Spring的其他组件都要使⽤到这个包⾥的类,Core模块是其他组件的基本核⼼。
当然你也可以在⾃⼰的应⽤系统中使⽤这些⼯具类。
SpringAOP示例与实现原理总结——传统springaop、基于切面注入、基于@Asp。。。
SpringAOP⽰例与实现原理总结——传统springaop、基于切⾯注⼊、基于@Asp。
⼀、代码实践1)经典的Spring Aop经典的spring aop,是基于动态代理技术的。
实现⽅式上,最常⽤的是实现MethodInterceptor接⼝来提供环绕通知,创建若⼲代理,然后使⽤ProxyBeanFactory配置⼯⼚bean,⽣成拦截器链,完成拦截。
⽰例如下:1package demo.spring;23import org.aopalliance.intercept.MethodInterceptor;4import org.aopalliance.intercept.MethodInvocation;5import org.junit.Test;6import org.junit.runner.RunWith;7import org.springframework.beans.factory.annotation.Autowired;8import org.springframework.test.context.ContextConfiguration;9import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;1011 @RunWith(SpringJUnit4ClassRunner.class)12 @ContextConfiguration("classpath:spring-config.xml")13public class TraditionalSpringAopDemo {14 @Autowired15private Service proxy;1617 @Test18public void test() {19 proxy.execute("hello world!");20 }21 }2223interface Service {24void execute(String str);25 }2627class ServiceImpl implements Service {28 @Override29public void execute(String str) {30 System.out.println("execute invoke: " + str);31 }32 }3334class Interceptor1 implements MethodInterceptor {35 @Override36public Object invoke(MethodInvocation methodInvocation) throws Throwable {37 System.out.println("interceptor1,before invoke");38 Object ret = methodInvocation.proceed();39 System.out.println("interceptor1,after invoke");40return ret;41 }42 }4344class Interceptor2 implements MethodInterceptor {45 @Override46public Object invoke(MethodInvocation methodInvocation) throws Throwable {47 System.out.println("interceptor2,before invoke");48 Object ret = methodInvocation.proceed();49 System.out.println("interceptor2,after invoke");50return ret;51 }52 }xml⽂件配置:1<?xml version="1.0" encoding="UTF-8"?>2<beans xmlns="/schema/beans"3 xmlns:xsi="/2001/XMLSchema-instance"4 xmlns:context="/schema/context"5 xmlns:aop="/schema/aop"6 xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /schema/context /schema/context/sprin 78<context:component-scan base-package="demo.spring"/>910<bean class="demo.spring.ServiceImpl" id="service"></bean>11<bean class="demo.spring.Interceptor1" id="interceptor1"></bean>12<bean class="demo.spring.Interceptor2" id="interceptor2"></bean>13<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="proxy">14<property name="target" ref="service"/>15<property name="interceptorNames">16<list>17<value>interceptor1</value>18<value>interceptor2</value>19</list>20</property>21</bean>22</beans>结果:interceptor1,before invokeinterceptor2,before invokeexecute invoke: hello world!interceptor2,after invokeinterceptor1,after invoke可以看到拦截链的执⾏过程与拦截器顺序的关系。
面试之Spring框架IOC和AOP的实现原理
⾯试之Spring框架IOC和AOP的实现原理本⽂讲的是⾯试之Spring框架IOC和AOP的实现原理, IoC(Inversion of Control) (1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,⽽不是传统实现中,由程序代码直接操控。
控制权由应⽤代码中转到了外部容器,控制权的转移是所。
IoC(Inversion of Control)(1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,⽽不是传统实现中,由程序代码直接操控。
控制权由应⽤代码中转到了外部容器,控制权的转移是所谓反转。
对于Spring⽽⾔,就是由Spring来控制对象的⽣命周期和对象之间的关系;IoC还有另外⼀个名字——“依赖注⼊(Dependency Injection)”。
从名字上理解,所谓依赖注⼊,即组件之间的依赖关系由容器在运⾏期决定,即由容器动态地将某种依赖关系注⼊到组件之中。
(2). 在Spring的⼯作⽅式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运⾏到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。
所有的类的创建、销毁都由 spring来控制,也就是说控制对象⽣存周期的不再是引⽤它的对象,⽽是spring。
对于某个具体的对象⽽⾔,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
(3). 在系统运⾏中,动态的向某个对象提供它所需要的其他对象。
(4). 依赖注⼊的思想是通过反射机制实现的,在实例化⼀个类时,它通过反射调⽤类中set⽅法将事先保存在HashMap中的类属性注⼊到类中。
总⽽⾔之,在传统的对象创建⽅式中,通常由调⽤者来创建被调⽤者的实例,⽽在Spring中创建被调⽤者的⼯作由Spring来完成,然后注⼊调⽤者,即所谓的依赖注⼊or控制反转。
Spring方法拦截器MethodInterceptor
Spring方法拦截器MethodInterceptor实现MethodInterceptor接口,在调用目标对象的方法时,就可以实现在调用方法之前、调用方法过程中、调用方法之后对其进行控制。
MethodInterceptor接口可以实现MethodBeforeAdvice接口、AfterReturningAdvice接口、ThrowsAdvice接口这三个接口能够所能够实现的功能,但是应该谨慎使用MethodInterceptor 接口,很可能因为一时的疏忽忘记最重要的MethodInvocation而造成对目标对象方法调用失效,或者不能达到预期的设想。
关于含有Advice的三种对目标对象的方法的增强,可以参考文章在Spring的IOC容器中装配AOP代理。
在在Spring的IOC容器中装配AOP代理的基础上,比较MethodInterceptor接口的实现与上面提及到的三种接口实现对目标对象方法的增强的功能效果。
我们将从应用中分离出日志切面,,将对日志的操作整合到实现MethodInterceptor接口的类SpringMethodInterceptor中,该实现类的代码如下所示:package org.shirdrn.spring.aop;import java.util.Date;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class SpringMethodInterceptor implements MethodInterceptor {public Object invoke(MethodInvocation invo) throws Throwable {Object[] object = invo.getArguments();try{String date1 = (new Date()).toLocaleString();System.out.println("信息:[MethodInterceptor]["+date1+"]用户"+object[0]+" 正在尝试登录陆系统...");Object returnObject = invo.proceed();String date2 = (new Date()).toLocaleString();System.out.println("信息:[MethodInterceptor]["+date2+"]用户"+object[0]+" 成功登录系统.");return returnObject;}catch(Throwable throwable){if(object[0].equals("Jessery")){throw new Exception("信息:[MethodInterceptor]不允许黑名单中用户"+object[0]+" 登录系统");}}return object;}}程序中,红色标示的代码行Object returnObject =invo.proceed();很关键,只有通过它来对目标对象方法调用,返回一个Object对象。
Spring中IOC和AOP的深入讲解
Spring中IOC和AOP的深⼊讲解前⾔Spring是⼀个开源框架,Spring是于2003 年兴起的⼀个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍⽣⽽来。
它是为了解决企业应⽤开发的复杂性⽽创建的。
Spring使⽤基本的JavaBean来完成以前只可能由EJB完成的事情。
然⽽,Spring的⽤途不仅限于服务器端的开发。
从简单性、可测试性和松耦合的⾓度⽽⾔,任何Java应⽤都可以从Spring中受益。
简单来说,Spring是⼀个轻量级的控制反转(IoC)和⾯向切⾯(AOP)的容器框架。
这篇⽂章主要讲 Spring 中的⼏个点,Spring 中的 IOC,AOP,下⼀篇说说 Spring 中的事务操作,注解和 XML 配置。
Spring 简介Spring 是⼀个开源的轻量级的企业级框架,其核⼼是反转控制 (IoC) 和⾯向切⾯ (AOP) 的容器框架。
我们可以把 Spring 看成是对象的容器,容器中可以包含很多对象,所以 Spring 有很多强⼤的功能。
⼀句话,Spring 是项⽬中对象的管家,负责管理项⽬中⽤到的所有对象。
所以在项⽬三层架构中,Spring 不属于某⼀特定层。
Spring 的 Hello World想要构建⼀个 Spring 的⼊门程序,我们需要导⼊ 4 个核⼼包和 2 个辅助包,创建⼀个实体类,最主要的是编写核⼼配置⽂件,applicationContext.xml 放在 src 下。
最后写⼀个测试类即可。
此时在测试类中我们不需要在使⽤ new 关键字去创建对象了。
这也正是 Spring 的作⽤所在,会⾃动给我创建对象。
上图展⽰的就是最基本的演⽰,也是很容易就理解了,配置⽂件中配置了 user 对象,我们通过加载配置⽂件来获取对象从⽽避免了使⽤ new 来创建。
AOP事务管理的原理与及三种实现方式
AOP事务管理的原理与及三种实现方式AOP(Aspect-Oriented Programming)即面向切面编程,是一种软件开发方法,主要用于解决分散在一个应用程序中的横切关注点(cross-cutting concerns)问题。
事务管理是AOP的一个典型应用场景,它主要用于保证一系列操作的原子性、一致性和隔离性。
本文将详细介绍AOP事务管理的原理以及三种常见的实现方式。
一、AOP事务管理原理1.拦截器执行顺序首先,AOP框架通过拦截器机制,将事务相关的拦截器按照一定的顺序进行执行。
常见的拦截器有前置拦截器(Before)、后置拦截器(After)、异常拦截器(AfterThrowing)、返回拦截器(AfterReturning)等。
2.事务传播和隔离级别在方法级别的事务管理中,每个被拦截的方法可以有不同的事务传播行为和隔离级别。
事务传播行为指的是当一个方法调用另外一个方法时,如何处理事务;隔离级别指的是事务之间的隔离程度。
3.事务切面的应用通过拦截器机制,将事务注解或者配置文件中的事务属性传递给事务管理器,然后由事务管理器根据事务属性进行事务操作。
实际应用中,可以使用Spring框架提供的AOP事务管理功能来实现对方法级别的事务控制。
根据AOP事务管理的原理,常见的AOP事务管理的实现方式有基于注解的方式、基于XML配置的方式和基于编程的方式。
1.基于注解的方式优点:(1)简单方便,只需在方法上加上注解即可进行事务管理。
(2)灵活可控,通过注解可以更细粒度地控制事务的传播行为和隔离级别。
(3)清晰明了,注解能够直观地体现出事务的特性。
缺点:(1)侵入性较强,需要在代码中添加注解。
(2)不能对第三方库中的方法进行事务管理。
2.基于XML配置的方式基于XML配置的方式是通过在配置文件中定义事务管理器、事务通知以及切点表达式等信息,来实现对方法级别的事务控制。
通过AOP框架读取配置文件,将事务相关的信息应用到需要进行事务管理的方法上。
