`

Spring中AOP的学习

阅读更多
今天对Proxy和cglib的原理进行了一些学习,主要是参考网上找来的资料:
准备工作,对cglig和proxy代理进行相关的学习。

1、cglib的学习,cglib是靠继承关系来实现代理的目的,即具体代码如下:
 public class AOPInstrumenter implements MethodInterceptor {
	private static Log logger = LogFactory.getLog(AOPInstrumenter.class);
	private Enhancer enhancer = new Enhancer();
	public Object getInstrumentedClass(Class clz) {
		enhancer.setSuperclass(clz);
		enhancer.setCallback(this);
		return enhancer.create();
	}
	public Object intercept(Object o, Method method, Object[] methodParameters,MethodProxy methodProxy) throws Throwable {
		logger.debug("Before Method =>" + method.getName());
		Object result = methodProxy.invokeSuper(o, methodParameters);
		logger.debug("After Method =>" + method.getName());
		return result;
	}
}




2、proxy代理,主要靠实现接口来实现代理的目的,即具体代码如下:
public class AOPHandler implements InvocationHandler {
	private static Log logger = LogFactory.getLog(AOPHandler.class);
	private List interceptors = null;
	private Object originalObject;
	/**
	 * 返回动态代理实例
	 * 
	 * @param obj
	 * @return
	 */
	public Object bind(Object obj) {
		this.originalObject = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}
	/**
	 * 在Invoke方法中,加载对应的Interceptor,并进行
	 * 预处理(before)、后处理(after)以及异常处理(exceptionThrow)过程
	 */
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		Object result = null;
		Throwable ex = null;
		InvocationInfo invInfo = new InvocationInfo(proxy, method, args,result, ex);
		logger.debug("Invoking Before Intercetpors!");
		invokeInterceptorsBefore(invInfo);
		try {
			logger.debug("Invoking Proxy Method!");
			result = method.invoke(originalObject, args);
			invInfo.setResult(result);
			logger.debug("Invoking After Method!");
			invokeInterceptorsAfter(invInfo);
		} catch (Throwable tr) {
			invInfo.setException(tr);
			logger.debug("Invoking exceptionThrow Method!");
			invokeInterceptorsExceptionThrow(invInfo);
			throw new AOPRuntimeException(tr);
		}
		return result;
	}
	/**
	 * 加载Interceptor
	 * 
	 * @return
	 */
	private synchronized List getIntercetors() {
		if (null == interceptors) {
			interceptors = new ArrayList();
			//Todo:读取配置,加载Interceptor实例
			interceptors.add(new MyInterceptor());
		}
		return interceptors;
	}
	/**
	 * 执行预处理方法
	 * 
	 * @param invInfo
	 */
	private void invokeInterceptorsBefore(InvocationInfo invInfo) {
		List interceptors = getIntercetors();
		int len = interceptors.size();
		for (int i = 0; i < len; i++) {
			((Interceptor) interceptors.get(i)).before(invInfo);
		}
	}
	/**
	 * 执行后处理方法
	 * 
	 * @param invInfo
	 */
	private void invokeInterceptorsAfter(InvocationInfo invInfo) {
		List interceptors = getIntercetors();
		int len = interceptors.size();
		for (int i = len - 1; i >= 0; i--) {
			((Interceptor) interceptors.get(i)).after(invInfo);
		}
	}
	/**
	 * 执行异常处理方法
	 * 
	 * @param invInfo
	 */
	private void invokeInterceptorsExceptionThrow(InvocationInfo invInfo) {
		List interceptors = getIntercetors();
		int len = interceptors.size();
		for (int i = len - 1; i >= 0; i--) {
			((Interceptor) interceptors.get(i)).exceptionThrow(invInfo);
		}
	}
}




public class AOPFactory {
	static AOPHandler txHandler ;
	private static Log logger = LogFactory.getLog(AOPFactory.class);
	/**
	 * 根据类名创建类实例
	 * 
	 * @param clzName
	 * @return
	 * @throws ClassNotFoundException
	 */
	public static Object getClassInstance(String clzName) {
		Class cls;
		try {
			cls = Class.forName(clzName);
			return (Object) cls.newInstance();
		} catch (ClassNotFoundException e) {
			logger.debug(e);
			throw new AOPRuntimeException(e);
		} catch (InstantiationException e) {
			logger.debug(e);
			throw new AOPRuntimeException(e);
		} catch (IllegalAccessException e) {
			logger.debug(e);
			throw new AOPRuntimeException(e);
		}
	}
	/**
	 * 根据传入的类名,返回AOP代理对象
	 * 
	 * @param clzName
	 * @return
	 */
	public static Object getAOPProxyedObject(String clzName) {
		txHandler = new AOPHandler();
		Object obj = getClassInstance(clzName);
		return txHandler.bind(obj);
	}

	/**
	 * @return Returns the txHandler.
	 */
	public static AOPHandler getTxHandler() {
		return txHandler;
	}
}



public interface Interceptor {
	public void before(InvocationInfo invInfo);
	public void after(InvocationInfo invInfo);
	public void exceptionThrow(InvocationInfo invInfo);
}


public class MyInterceptor implements Interceptor {
	private static Log logger = LogFactory.getLog(MyInterceptor.class);
	public void before(InvocationInfo invInfo) {
		logger.debug("Pre-processing");
	}
	public void after(InvocationInfo invInfo) {
		logger.debug("Post-processing");
	}
	public void exceptionThrow(InvocationInfo invInfo) {
		logger.debug("Exception-processing");
	}
}






3、Spring中AOP的实现。剖析Spring中的cglig和proxy。
Spring中的核心模块为:bean和aop;其中bean模块对aop提供了支持。
public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {
public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
		String beanName = transformedBeanName(name);
		Object bean = null;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = null;
		synchronized (this.singletonCache) {
			sharedInstance = this.singletonCache.get(beanName);
		}
		if (sharedInstance != null) {
			if (sharedInstance == CURRENTLY_IN_CREATION) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
			}
			bean = getObjectForSharedInstance(name, sharedInstance);		}

		else {
			// Check if bean definition exists in this factory.
			RootBeanDefinition mergedBeanDefinition = null;
			try {
				mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Not found -> check parent.
				if (this.parentBeanFactory instanceof AbstractBeanFactory) {
					// Delegation to parent with args only possible for AbstractBeanFactory.
					return ((AbstractBeanFactory) this.parentBeanFactory).getBean(name, requiredType, args);
				}
				else if (this.parentBeanFactory != null && args == null) {
					// No args -> delegate to standard getBean method.
					return this.parentBeanFactory.getBean(name, requiredType);
				}
				throw ex;
			}

			checkMergedBeanDefinition(mergedBeanDefinition, beanName, requiredType, args);

			// Create bean instance.
			if (mergedBeanDefinition.isSingleton()) {
				synchronized (this.singletonCache) {
					// re-check singleton cache within synchronized block
					sharedInstance = this.singletonCache.get(beanName);
					if (sharedInstance == null) {
						if (logger.isInfoEnabled()) {
							logger.info("Creating shared instance of singleton bean '" + beanName + "'");
						}
						this.singletonCache.put(beanName, CURRENTLY_IN_CREATION);
						try {
							sharedInstance = createBean(beanName, mergedBeanDefinition, args);
							this.singletonCache.put(beanName, sharedInstance);
						}
						catch (BeansException ex) {
							this.singletonCache.remove(beanName);
							throw ex;
						}
					}
				}
				bean = getObjectForSharedInstance(name, sharedInstance);
			}
			else {
				// It's a prototype -> create a new instance.
				bean = createBean(name, mergedBeanDefinition, args);
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) {
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
		return bean;
	}
}





public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {
	protected Object getObjectForSharedInstance(String name, Object beanInstance) throws BeansException {
		String beanName = transformedBeanName(name);

		// Don't let calling code try to dereference the
		// bean factory if the bean isn't a factory.
		if (isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		if (beanInstance instanceof FactoryBean) {
			if (!isFactoryDereference(name)) {
				// Return bean instance from factory.
				FactoryBean factory = (FactoryBean) beanInstance;
				if (logger.isDebugEnabled()) {
					logger.debug("Bean with name '" + beanName + "' is a factory bean");
				}
				try {
					beanInstance = factory.getObject();
				}
				catch (Exception ex) {
					throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
				}
				if (beanInstance == null) {
					throw new FactoryBeanNotInitializedException(
					    beanName, "FactoryBean returned null object: " +
							"probably not fully initialized (maybe due to circular bean reference)");
				}
			}
			else {
	 			// The user wants the factory itself.
				if (logger.isDebugEnabled()) {
					logger.debug("Calling code asked for FactoryBean instance for name '" + beanName + "'");
				}
			}
		}

		return beanInstance;
	}
}


public class ProxyFactoryBean extends AdvisedSupport
    implements FactoryBean, BeanFactoryAware, AdvisedSupportListener {
	public Object getObject() throws BeansException {
		return this.singleton ? getSingletonInstance() : newPrototypeInstance();
	}


	private Object getSingletonInstance() {
		if (this.singletonInstance == null) {
			super.setFrozen(this.freezeProxy);
			this.singletonInstance = createAopProxy().getProxy();
		}
		return this.singletonInstance;
	}
}


final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
	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);
	}
}


public class Cglib2AopProxy implements AopProxy, Serializable {
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			Class targetClass = this.advised.getTargetSource().getTargetClass();
			logger.debug("Creating CGLIB2 proxy" +
					(targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
		}

		Enhancer enhancer = new Enhancer();
		try {
			Class rootClass = this.advised.getTargetSource().getTargetClass();

			if (AopUtils.isCglibProxyClass(rootClass)) {
				enhancer.setSuperclass(rootClass.getSuperclass());
			}
			else {
				enhancer.setSuperclass(rootClass);
			}

			enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised));
			enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));

			Callback[] callbacks = getCallbacks(rootClass);
			enhancer.setCallbacks(callbacks);

			if(CglibUtils.canSkipConstructorInterception()) {
				enhancer.setInterceptDuringConstruction(false);
			}
			
			Class[] types = new Class[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			enhancer.setCallbackTypes(types);

			// generate the proxy class and create a proxy instance
			Object proxy;
			if (this.constructorArgs != null) {
				proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
			}
			else {
				proxy = enhancer.create();
			}

			return proxy;
		}
		catch (CodeGenerationException ex) {
			throw new AspectException("Couldn't generate CGLIB subclass of class '" +
					this.advised.getTargetSource().getTargetClass() + "': " +
					"Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (IllegalArgumentException ex) {
			throw new AspectException("Couldn't generate CGLIB subclass of class '" +
					this.advised.getTargetSource().getTargetClass() + "': " +
					"Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (Exception ex) {
			// TargetSource.getTarget failed
			throw new AspectException("Unexpected AOP exception", ex);
		}
	}
}
分享到:
评论

相关推荐

    Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结

    Spring AOP,即面向切面编程,是Spring框架的核心组件之一,它允许程序员在不修改原有业务代码的情况下,对程序进行功能增强。...通过学习和实践,你可以更好地在Spring框架中利用AOP解决实际问题。

    spring aop 学习笔记

    本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际应用。 1. **核心概念** - **切面(Aspect)**:切面是关注点的模块化,包含业务逻辑之外的横切关注点,如日志、事务管理。 - **连接点(Join Point...

    Spring IOC AOP学习示例

    Spring IOC AOP学习示例代码,包含Spring常用操作示例和所有所需jar文件。参考博客:http://blog.csdn.net/daijin888888/article/details/51735291

    spring-aop.xsd

    `spring-aop.xsd`文件是Spring AOP配置的XML Schema定义文件,用于指导和验证XML配置中的元素和属性,确保其符合规范,同时也为IDE提供代码提示和自动补全功能,提高开发效率。 在Java开发中,AOP(Aspect Oriented...

    Spring.net Aop 例子

    通过这个例子,你可以学习到如何在Spring.NET环境中实现AOP,理解动态代理的工作原理,并掌握如何在实际项目中应用AOP来提高代码的灵活性和可维护性。这将有助于你编写更加模块化、易于维护的软件系统。

    spring_aop.rar_spring_aop

    通过这个实例工程,学习者可以直观地理解Spring AOP的工作原理,如何定义切面、配置通知以及如何在实际项目中应用。同时,它还能帮助开发者理解如何在不修改原始业务代码的情况下,实现通用功能的插入,提高代码的可...

    简单spring aop 例子

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理、安全性等。本示例将简要介绍如何在Spring应用中实现AOP,通过实际的...

    spring 3.0 aop 实例

    在Spring中,AOP主要用于处理系统级别的横切关注点,如日志、事务、安全性等。它通过定义切入点(Pointcut)和通知(Advice)来实现。切入点是程序执行流程中的某个特定位置,而通知是在切入点触发时执行的代码。 1...

    spring2.5AOPdemo详细资料

    学习这个Demo,你需要理解每个部分的作用,分析源代码中的注解和逻辑,了解它们是如何与Spring AOP机制配合的。此外,通过运行测试用例,观察输出结果,你可以更深入地理解AOP的实际效果和应用场景。 总的来说,...

    Spring AOP完整例子

    Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许开发者在不修改源代码的情况下,通过...这个例子提供了学习Spring AOP实际操作的宝贵资源,通过阅读源码和运行测试,你将对Spring AOP有更全面的认识。

    2024-spring-aop学习项目

    《深入理解Spring AOP:2024春季学习项目指南》 ...通过这个2024春季AOP学习项目,开发者将有机会亲手实践上述概念,深入理解Spring AOP的精髓,从而在实际项目中更好地运用这一强大的工具,提升代码质量与工程效率。

    spring AspectJ aop学习

    当我们谈论"spring AspectJ aop学习"时,我们将深入探讨Spring AOP如何结合AspectJ来实现更灵活的模块化和解耦。 首先,让我们理解AOP的概念。面向切面编程(Aspect Oriented Programming)是一种编程范式,旨在将...

    Spring3.1AOP简单例子

    在本示例中,我们将深入探讨Spring框架的3.1版本中的核心概念之一:面向切面编程(Aspect-Oriented Programming,简称AOP)。AOP是Spring框架的强大特性,它允许我们在应用程序中实现关注点的分离,使得我们可以将横...

    spring-aop-4.2.xsd.zip

    标题中的"spring-aop-4.2.xsd.zip"表明这是一个与Spring框架的AOP(面向切面编程)相关的资源,版本为...开发者可以通过解析和学习这个XSD文件,更好地掌握Spring AOP的配置语法,从而实现更高效和精确的面向切面编程。

    spring-aop-4.2.6.RELEASE.zip

    在IT行业中,Spring框架无疑是Java开发领域的中流砥柱,而Spring AOP则是其核心组件之一。本资料包"spring-aop-4.2.6.RELEASE.zip"正是针对Spring AOP的一个重要版本,它与"spring-framework.zip"一同构成了强大的...

    Spring实现AOP的4种方式

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点从业务逻辑中分离出来,比如日志记录、事务管理、权限检查等。本篇文章将详细探讨Spring实现AOP的四种主要方法:基于代理的方式、...

    Spring AOP学习资料(pdf)

    ### Spring AOP 学习资料知识点总结 #### 一、Spring AOP 概念与背景 **Spring AOP**(面向切面编程)是Spring框架中的一个重要组成部分,它通过预定义的切入点来分离关注点,使得核心业务逻辑更加清晰,同时能够...

    spring AOP入门教程

    - **SpringAOP.avi**:可能是一个视频教程,详细讲解了Spring AOP的概念和实践。 - **SpringAOP.doc**:可能是文档教程,包含了详细的步骤和示例代码。 - **SpringAOP_src.rar**:源代码示例,供你参考和实践。 - **...

    spring-aop

    Spring AOP,全称为Aspect...在`section6-AOP`这个压缩包中,可能包含了演示Spring AOP使用的代码示例,可以直接导入项目进行学习和实践。通过深入理解和运用这些示例,可以更好地掌握Spring AOP的核心概念和实际应用。

    SpringAop学习笔记以及实现Demo

    **Spring AOP 学习笔记及实现Demo** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。AOP的主要目的...

Global site tag (gtag.js) - Google Analytics