`
talentkep
  • 浏览: 101494 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

spring aop内部实现

    博客分类:
阅读更多

AOP功能强大,但是spring是如何来实现AOP技术的呢?
SPRING是通过动态代理来实现AOP的,SPRING内部提供了2种实现机制
1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理

Java代码 复制代码
  1. org.springframework.aop.framework.JdkDynamicAopProxy   
  2.     public Object getProxy(ClassLoader classLoader) {   
  3.         if (logger.isDebugEnabled()) {   
  4.             Class targetClass = this.advised.getTargetSource().getTargetClass();   
  5.             logger.debug("Creating JDK dynamic proxy" +   
  6.                     (targetClass != null ? " for [" + targetClass.getName() + "]" : ""));   
  7.         }   
  8.         Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);   
  9.         return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);   
  10.     }   
  11.   
  12. org.springframework.aop.framework.ReflectiveMethodInvocation   
  13. public Object proceed() throws Throwable {   
  14.         //  We start with an index of -1 and increment early.   
  15.         if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {   
  16.             return invokeJoinpoint();   
  17.         }   
  18.   
  19.         Object interceptorOrInterceptionAdvice =   
  20.             this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);   
  21.         if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {   
  22.             // Evaluate dynamic method matcher here: static part will already have   
  23.             // been evaluated and found to match.   
  24.             InterceptorAndDynamicMethodMatcher dm =   
  25.                 (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;   
  26.             if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {   
  27.                 return dm.interceptor.invoke(this);   
  28.             }   
  29.             else {   
  30.                 // Dynamic matching failed.   
  31.                 // Skip this interceptor and invoke the next in the chain.   
  32.                 return proceed();   
  33.             }   
  34.         }   
  35.         else {   
  36.             // It's an interceptor, so we just invoke it: The pointcut will have   
  37.             // been evaluated statically before this object was constructed.   
  38.             return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);   
  39.         }   
  40.     }  
org.springframework.aop.framework.JdkDynamicAopProxy
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			Class targetClass = this.advised.getTargetSource().getTargetClass();
			logger.debug("Creating JDK dynamic proxy" +
					(targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
		}
		Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

org.springframework.aop.framework.ReflectiveMethodInvocation
public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
		    this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
			    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}



2.如果是没有接口声明的类呢?SPRING通过CGLIB包和内部类来实现

Java代码 复制代码
  1. private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {   
  2.   
  3.         private final Object target;   
  4.   
  5.         public StaticUnadvisedInterceptor(Object target) {   
  6.             this.target = target;   
  7.         }   
  8.   
  9.         public Object intercept(Object proxy, Method method, Object[] args,   
  10.                 MethodProxy methodProxy) throws Throwable {   
  11.   
  12.             Object retVal = methodProxy.invoke(target, args);   
  13.             return massageReturnTypeIfNecessary(proxy, target, retVal);   
  14.         }   
  15.     }   
  16.   
  17.   
  18.     /**  
  19.      * Method interceptor used for static targets with no advice chain, when the  
  20.      * proxy is to be exposed.  
  21.      */  
  22.     private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {   
  23.   
  24.         private final Object target;   
  25.   
  26.         public StaticUnadvisedExposedInterceptor(Object target) {   
  27.             this.target = target;   
  28.         }   
  29.   
  30.         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {   
  31.             Object oldProxy = null;   
  32.             try {   
  33.                 oldProxy = AopContext.setCurrentProxy(proxy);   
  34.                 Object retVal = methodProxy.invoke(target, args);   
  35.                 return massageReturnTypeIfNecessary(proxy, target, retVal);   
  36.             }   
  37.             finally {   
  38.                 AopContext.setCurrentProxy(oldProxy);   
  39.             }   
  40.         }   
  41.     }   
  42.   
  43.   
  44.     /**  
  45.      * Interceptor used to invoke a dynamic target without creating a method  
  46.      * invocation or evaluating an advice chain. (We know there was no advice  
  47.      * for this method.)  
  48.      */  
  49.     private class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {   
  50.   
  51.         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {   
  52.             Object target = advised.getTargetSource().getTarget();   
  53.             try {   
  54.                 Object retVal = methodProxy.invoke(target, args);   
  55.                 return massageReturnTypeIfNecessary(proxy, target, retVal);   
  56.             }   
  57.             finally {   
  58.                 advised.getTargetSource().releaseTarget(target);   
  59.             }   
  60.         }   
  61.     }   
  62.   
  63.   
  64.     /**  
  65.      * Interceptor for unadvised dynamic targets when the proxy needs exposing.  
  66.      */  
  67.     private class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {   
  68.   
  69.         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {   
  70.             Object oldProxy = null;   
  71.             Object target = advised.getTargetSource().getTarget();   
  72.             try {   
  73.                 oldProxy = AopContext.setCurrentProxy(proxy);   
  74.                 Object retVal = methodProxy.invoke(target, args);   
  75.                 return massageReturnTypeIfNecessary(proxy, target, retVal);   
  76.             }   
  77.             finally {   
  78.                 AopContext.setCurrentProxy(oldProxy);   
  79.                 advised.getTargetSource().releaseTarget(target);   
  80.             }   
  81.         }   
  82.     }  
private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {

		private final Object target;

		public StaticUnadvisedInterceptor(Object target) {
			this.target = target;
		}

		public Object intercept(Object proxy, Method method, Object[] args,
				MethodProxy methodProxy) throws Throwable {

			Object retVal = methodProxy.invoke(target, args);
			return massageReturnTypeIfNecessary(proxy, target, retVal);
		}
	}


	/**
	 * Method interceptor used for static targets with no advice chain, when the
	 * proxy is to be exposed.
	 */
	private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

		private final Object target;

		public StaticUnadvisedExposedInterceptor(Object target) {
			this.target = target;
		}

		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			try {
				oldProxy = AopContext.setCurrentProxy(proxy);
				Object retVal = methodProxy.invoke(target, args);
				return massageReturnTypeIfNecessary(proxy, target, retVal);
			}
			finally {
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}


	/**
	 * Interceptor used to invoke a dynamic target without creating a method
	 * invocation or evaluating an advice chain. (We know there was no advice
	 * for this method.)
	 */
	private class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {

		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object target = advised.getTargetSource().getTarget();
			try {
				Object retVal = methodProxy.invoke(target, args);
				return massageReturnTypeIfNecessary(proxy, target, retVal);
			}
			finally {
				advised.getTargetSource().releaseTarget(target);
			}
		}
	}


	/**
	 * Interceptor for unadvised dynamic targets when the proxy needs exposing.
	 */
	private class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			Object target = advised.getTargetSource().getTarget();
			try {
				oldProxy = AopContext.setCurrentProxy(proxy);
				Object retVal = methodProxy.invoke(target, args);
				return massageReturnTypeIfNecessary(proxy, target, retVal);
			}
			finally {
				AopContext.setCurrentProxy(oldProxy);
				advised.getTargetSource().releaseTarget(target);
			}
		}
	}




我们自己也可以来试试
1.jdk proxy方式

先来一个接口
IHelloWorld.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. public interface IHelloWorld {   
  4.   
  5.     public void print(String name);   
  6.        
  7.     public void write(String sth);   
  8. }  
package kris.aop.test;

public interface IHelloWorld {

	public void print(String name);
	
	public void write(String sth);
}




再来一个实现

HelloWorld.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. public class HelloWorld implements IHelloWorld {   
  4.   
  5.     public void print(String name){   
  6.         System.out.println("HelloWorld "+name);   
  7.     }   
  8.   
  9.     public void write(String sth) {   
  10.         System.out.println("write "+sth);   
  11.            
  12.     }   
  13.   
  14. }  
package kris.aop.test;

public class HelloWorld implements IHelloWorld {

	public void print(String name){
		System.out.println("HelloWorld "+name);
	}

	public void write(String sth) {
		System.out.println("write "+sth);
		
	}

}



代理类

DefaultInvocationHandler.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. import java.lang.reflect.InvocationHandler;   
  4. import java.lang.reflect.Method;   
  5.   
  6. public class DefaultInvocationHandler implements InvocationHandler {   
  7.   
  8.     /**  
  9.      * 替换外部class调用的方法  
  10.      * obj      外部已经已经包装好InvocationHandler的实例  
  11.      * method   外部方法  
  12.      * args     方法参数  
  13.      */  
  14.     public Object invoke(Object obj, Method method, Object[] args)   
  15.             throws Throwable {   
  16.         String s1 []={"kris"};   
  17.         String s2 []={"anyone"};   
  18.         IHelloWorld ihw=new HelloWorld();   
  19.         System.out.println("start!");   
  20.         method.invoke(ihw,args);   
  21.         method.invoke(ihw,s1);   
  22.         Object o=method.invoke(ihw,s2);   
  23.         System.out.println("stop!");   
  24.         return o;   
  25.     }   
  26.   
  27. }  
package kris.aop.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DefaultInvocationHandler implements InvocationHandler {

	/**
	 * 替换外部class调用的方法
	 * obj		外部已经已经包装好InvocationHandler的实例
	 * method	外部方法
	 * args		方法参数
	 */
	public Object invoke(Object obj, Method method, Object[] args)
			throws Throwable {
		String s1 []={"kris"};
		String s2 []={"anyone"};
		IHelloWorld ihw=new HelloWorld();
		System.out.println("start!");
		method.invoke(ihw,args);
		method.invoke(ihw,s1);
		Object o=method.invoke(ihw,s2);
		System.out.println("stop!");
		return o;
	}

}



测试类
Test.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. import java.lang.reflect.InvocationHandler;   
  4. import java.lang.reflect.Proxy;   
  5.   
  6. public class Test {   
  7.   
  8.     public static void main(String args []){   
  9.         Class clazz = new HelloWorld().getClass();   
  10.         ClassLoader cl = clazz.getClassLoader();   
  11.         Class classes [] = clazz.getInterfaces();   
  12.         InvocationHandler ih=new DefaultInvocationHandler();   
  13.         //用InvocationHandler给HelloWorld进行AOP包装   
  14.         IHelloWorld ihw=(IHelloWorld) Proxy.newProxyInstance(cl,classes,ih);   
  15.         ihw.print("test");   
  16.         ihw.write("test");   
  17.     }   
  18. }  
package kris.aop.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {

	public static void main(String args []){
		Class clazz = new HelloWorld().getClass();
		ClassLoader cl = clazz.getClassLoader();
		Class classes [] = clazz.getInterfaces();
		InvocationHandler ih=new DefaultInvocationHandler();
		//用InvocationHandler给HelloWorld进行AOP包装
		IHelloWorld ihw=(IHelloWorld) Proxy.newProxyInstance(cl,classes,ih);
		ihw.print("test");
		ihw.write("test");
	}
}




2.用CGLIB包实现,首先不要忘了引入那个包

Java代码 复制代码
  1. package kris.aop.cglib.test;   
  2.   
  3. public class HelloWorld {   
  4.   
  5.     public void print(String name){   
  6.         System.out.println("HelloWorld "+name);   
  7.     }   
  8.   
  9.     public void write(String sth) {   
  10.         System.out.println("write "+sth);   
  11.            
  12.     }   
  13.     public void print(){   
  14.         System.out.println("HelloWorld");   
  15.     }   
  16.   
  17. }  
package kris.aop.cglib.test;

public class HelloWorld {

	public void print(String name){
		System.out.println("HelloWorld "+name);
	}

	public void write(String sth) {
		System.out.println("write "+sth);
		
	}
	public void print(){
		System.out.println("HelloWorld");
	}

}



代理类(没用内部类,看起来清楚点)

Java代码 复制代码
  1. package kris.aop.cglib.test;   
  2.   
  3. import java.lang.reflect.Method;   
  4.   
  5. import net.sf.cglib.proxy.MethodInterceptor;   
  6. import net.sf.cglib.proxy.MethodProxy;   
  7.   
  8. public class MethodInterceptorImpl implements MethodInterceptor {   
  9.   
  10.     public Object intercept(Object obj, Method method, Object[] args,   
  11.             MethodProxy proxy) throws Throwable {   
  12.   
  13.         System.out.println(method);   
  14.   
  15.         proxy.invokeSuper(obj, args);   
  16.   
  17.         return null;   
  18.     }   
  19. }  
package kris.aop.cglib.test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MethodInterceptorImpl implements MethodInterceptor {

	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {

		System.out.println(method);

		proxy.invokeSuper(obj, args);

		return null;
	}
}



测试类

Java代码 复制代码
  1. package kris.aop.cglib.test;   
  2.   
  3. import net.sf.cglib.proxy.Enhancer;   
  4.   
  5. public class Test {   
  6.   
  7.     public static void main(String[] args) {   
  8.   
  9.         Enhancer enhancer = new Enhancer();   
  10.   
  11.         enhancer.setSuperclass(HelloWorld.class);   
  12.         //设置回调方法实现类   
  13.         enhancer.setCallback(new MethodInterceptorImpl());   
  14.         //实例化已经添加回调实现的HELLOWORLD实例   
  15.         HelloWorld my = (HelloWorld) enhancer.create();   
  16.   
  17.         my.print();   
  18.     }   
  19.   
  20. }  
分享到:
评论

相关推荐

    初探spring aop内部实现 java

    本篇文章将深入探讨Spring AOP的内部实现,以及如何通过源代码理解其DataSource实现和FactoryBean模式。 首先,让我们了解AOP的基本概念。AOP的核心思想是“切面”,它封装了特定的关注点,如日志记录、事务管理、...

    Spring AOP框架实现的结构分析

    最后,本文的目标是从实现的角度来认识 SpringAOP 框架,观察的角度是从外部接口、内部实现、组成部分、执行过程四个方面来认识 SpringAOP 框架。本文的风格是首先列出 AOP 的基本概念,然后介绍框架所涉及到的核心...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    Spring AOP在内部也是基于类似的方式工作,但它的实现更为复杂和高效。它不仅可以处理接口代理,还可以处理基于类的代理,支持CGLIB库生成字节码实现。此外,Spring AOP还提供了一套强大的切点表达式和注解,使得...

    spring aop demo 两种实现方式

    本示例提供了一种通过注解和配置文件两种方式实现Spring AOP的方法。 首先,我们来详细讲解通过注解实现Spring AOP。在Spring中,我们可以使用`@Aspect`注解来定义一个切面,这个切面包含了多个通知(advice),即...

    Spring  AOP实现方法大全

    【Spring AOP实现方法大全】 在Spring框架中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种强大的设计模式,它允许我们在不修改业务代码的情况下,插入额外的功能,比如日志记录、事务管理等。在...

    spring aop spring aop

    Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的重要组成部分,用于实现横切关注点的模块化。它允许开发者定义“切面”,将那些与业务逻辑无关,却为多个对象共有的行为(如日志、...

    SpringAOP.rar_springAOP

    使用Spring AOP,可以在方法执行前后自动记录日志,无需在每个方法内部添加日志代码。 3.2 事务管理 Spring AOP提供声明式事务管理,可以在切点上定义事务边界,使得事务处理代码不再侵入业务逻辑。 3.3 安全控制...

    使用Spring配置文件实现AOP

    在Spring的XML配置文件中,我们可以创建一个`<aop:config>`元素,并在其内部定义`<aop:advisor>`来创建Advisor。Advisor的`advice-ref`属性用于指定通知bean的ID,`pointcut-ref`属性用于指定切点bean的ID。 2. ...

    第四章:Spring AOP API 设计模式1

    9. **享元模式(Flyweight)**:享元模式在Spring AOP中不太直接体现,但在Spring框架的其他部分,如缓存管理,可能会用到此模式来减少内存消耗,通过共享大量细粒度对象的内部状态来降低内存占用。 10. **代理模式...

    在自定义spring aop中使用el获取拦截方法的变量值。

    Spring AOP通过动态代理实现,有两种代理方式:JDK动态代理和CGLIB代理。JDK代理用于接口实现类,而CGLIB代理用于无接口或非代理类。 EL是JavaServer Faces (JSF) 和其他Java技术中用于在视图层解析表达式并获取...

    SpringAop的简单理解.pdf

    AspectJ是一种更全面的AOP解决方案,它通过编译器织入和类装载期织入来处理AOP,而SpringAOP则是通过动态代理技术来实现AOP。 要让Spring项目支持AOP,需要通过特定的配置来开启aspectj代理的支持。有基于XML的配置...

    第五章:Spring AOP 在 Spring Framework 内部应用1

    本章主要探讨了Spring AOP在Spring框架内部的多种应用,包括事件处理、事务管理和缓存等关键功能。 首先,我们来看Spring AOP在Spring事件(Events)中的应用。Spring事件模型允许应用程序组件之间进行异步通信。当...

    springaop

    标题 "springaop" 暗示我们关注的是Spring框架中的AOP(面向切面编程)模块。在Spring框架中,AOP是一种强大的工具,它允许程序员定义“切面”,这些切面可以封装横切关注点,如日志、事务管理、性能监控等,将它们...

    spring-aop AND proxy

    标签“源码”意味着这篇博客可能深入解析了Spring AOP的内部工作机制,包括如何通过代理机制实现切面的织入,以及Spring AOP的相关核心类如`Advised`、`ProxyFactoryBean`、`DefaultAdvisorAdapterRegistry`等。...

    Java spring AOP源码

    Spring框架提供了一种强大的AOP实现方式,支持声明式的AOP,并且与Spring容器紧密结合。 #### 关键知识点解析 **1. **Spring AOP对于最外层函数的拦截范围** Spring AOP对于最外层的函数只拦截`public`方法,不...

    spring aop管理xml版

    了解并熟练掌握Spring AOP的XML配置,能够帮助我们更好地实现代码的解耦,提高代码的可维护性和可复用性。通过合理的AOP设计,可以将关注点分离,使我们的业务逻辑更加清晰,同时减少重复代码,提升开发效率。

    springAOP-dome

    在这个名为"springAOP-dome"的实例中,我们将探讨如何利用Spring AOP实现一个简单的日志记录功能,以作为入门学习。 首先,了解AOP的基本概念是必要的。面向切面编程是一种编程范式,旨在解决程序中的横切关注点,...

    Spring AOP 项目

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要组成部分,它提供了在Java应用中实现切面编程的能力。在传统的面向对象编程中,关注点分离(例如日志、事务管理)往往与业务逻辑...

    spring aop 源码解析

    在本文中,我们将深入探讨Spring AOP的源码,理解其内部机制和工作原理。 首先,我们需要知道Spring AOP的核心概念——切面(Aspect)、通知(Advice)、连接点(Join Point)、切入点(Pointcut)和代理(Proxy)...

    Spring框架+SpringAOP动态代理

    ### Spring框架+SpringAOP动态代理 #### 一、Spring AOP 动态代理概述 在探讨Spring AOP(Aspect-Oriented Programming,面向切面编程)中的动态代理之前,我们首先简要回顾一下AOP的基本概念。面向切面编程是一种...

Global site tag (gtag.js) - Google Analytics