Spring AOP源码分析(生成代理对象)
2016-05-08 23:36
851 查看
AOP基本概述
Advice(通知)
BeforeAdvice
package org.springframework.aop; import java.lang.reflect.Method; public interface MethodBeforeAdvice extends BeforeAdvice { void before(Method method, Object[] args, Object target) throws Throwable; }
before是回调方法,在Advice中配置了目标方法后,会在调用目标方法时被回调。
参数:
method:目标方法
args:目标方法的输入参数
target:目标对象
AfterReturningAdvice
package org.springframework.aop; import java.lang.reflect.Method; public interface AfterReturningAdvice extends AfterAdvice { void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable; }
在目标方法调用结束并正常返回时,接口被回调
ThrowsAdvice
public interface ThrowsAdvice extends AfterAdvice { }
抛出异常时被回调,AOP使用反射实现(方法名叫AfterThrowing?)
PointCut(切入点)
public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher(); Pointcut TRUE = TruePointcut.INSTANCE; }
PointCut是通过MethodMatcher 进行切入点方法匹配的,判断是否需要对当前方法进行增强处理。
通过JdkRegexpMethodPointcut理解MethodMatcher:
在JdkRegexpMethodPointcut的基类StaticMethodMatcherPointcut中设置MethodMatcher为StaticMethodMatcherPointcut(StaticMethodMatcher)
public abstract class StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut { @Override public final MethodMatcher getMethodMatcher() { return this; } }
在JdkRegexpMethodPointcut中通过正则表达式匹配需要增强的方法:
protected boolean matches(String pattern, int patternIndex) { Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern); return matcher.matches(); }
在NameMatchMethodPointcut中通过方法名进行方法的匹配:
@Override public boolean matches(Method method, Class<?> targetClass) { for (String mappedName : this.mappedNames) { if (mappedName.equals(method.getName()) || isMatch(method.getName(), mappedName)) { return true; } } return false; } protected boolean isMatch(String methodName, String mappedName) { return PatternMatchUtils.simpleMatch(mappedName, methodName); }
Advisor(通知器)
通知器负责把切入点和增强处理接合起来。在切点处决定使用哪个通知
AOP设计与实现
JVM动态代理
JDK和CGLIB都是用动态代理实现的AopProxy代理对象
Spring中,是通过ProxyFactoryBean来完成代理对象的生成的ProxyConfig
数据基类,为ProxyFactoryBean这样的子类提供配置属性。AdvisedSupport
AOP对通知和通知器的操作,对不同的AOP代理的生成都是一样的。对于具体生代理类,由AdvisedSupport的子类来做。ProxyCreatorSupport
子类创建AOP代理类的辅助ProxyFactoryBean
IOC容器中声明式配置,生成代理类ProxyFactory
编程式使用,生成代理类AspectJProxyFactory
需要使用AspectJ功能的AOP应用,这个起到集成Spring和AspectJ的作用具体AOP代理对象的生成是由ProxyFactoryBean、ProxyFactory、AspectJProxyFactory完成的。
如何配置ProxyFactory?
<bean id="testAdvisor" class="com.abc.TestAdvisor" /> <!-- 通知器,实现了目标对象需要增强的切面行为,也就是通知 --> <!-- 这里我理解的是被代理的bean的scope如果是prototype,那么这个代理Bean就是prototype --> <bean id="testAop" class="org.springframework.aop.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.test.AbcInterface</value> </property> <property name="target"> <!-- 目标对象 --> <bean class="com.abc.TestTarget" /> </property> <property name="interceptorNames"> <!-- 需要拦截的方法接口,通知器 --> <list> <value> testAdvisor </value> </list> </property> </bean>
代理对象生成过程总览
以singleTon为例:代理对象获取入口:
ProxyFactoryBean的getObjectAopProxy生成过程:
ProxyFactoryBean的getObject获取代理对象
@Override public Object getObject() throws BeansException { //初始化通知器链,为代理对象配置通知器链。 initializeAdvisorChain(); //区分SingleTon和ProtoType,生成对应的Proxy if (isSingleton()) { // 只有SingleTon的Bean才会一开始就初始化,ProtoType的只有在请求的时候才会初始化,代理也一样 return getSingletonInstance(); } else { if (this.targetName == null) { logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " + "Enable prototype proxies by setting the 'targetName' property."); } return newPrototypeInstance(); } }
关于initializeAdvisorChain
ProxyFactoryBean的initializeAdvisorChain这个初始化过程有一个标志位advisorChainInitialized,这个标志用来表示通知器链是否已经初始化。
这个就是通知器链,在AdvisorSupport中:
private List<Advisor> advisors = new LinkedList<Advisor>();
如果已经初始化,那么这里不会再初始化,直接返回。初始化只是在应用第一次通过ProxyFactoryBean获取代理对象的时候。
完成这个初始化之后,接着会读取配置中出现的所有通知器(把通知器的名字交给容器的getBean,IOC容器的回调获取通知器),把通知器加入拦截器链(addAdvisoronChainCreation实现)。
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException { if (this.advisorChainInitialized) { return; } if (!ObjectUtils.isEmpty(this.interceptorNames)) { if (this.beanFactory == null) { throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " + "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames)); } // Globals can't be last unless we specified a targetSource using the property... if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) && this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) { throw new AopConfigException("Target required after globals"); } // Materialize interceptor chain from bean names. for (String name : this.interceptorNames) { if (logger.isTraceEnabled()) { logger.trace("Configuring advisor or advice '" + name + "'"); } if (name.endsWith(GLOBAL_SUFFIX)) { if (!(this.beanFactory instanceof ListableBeanFactory)) { throw new AopConfigException( "Can only use global advisors or interceptors with a ListableBeanFactory"); } addGlobalAdvisor((ListableBeanFactory) this.beanFactory, name.substring(0, name.length() - GLOBAL_SUFFIX.length())); } else { // If we get here, we need to add a named interceptor. // We must check if it's a singleton or prototype. Object advice; if (this.singleton || this.beanFactory.isSingleton(name)) { // Add the real Advisor/Advice to the chain. advice = this.beanFactory.getBean(name); } else { // It's a prototype Advice or Advisor: replace with a prototype. // Avoid unnecessary creation of prototype bean just for advisor chain initialization. advice = new PrototypePlaceholderAdvisor(name); } addAdvisorOnChainCreation(advice, name); } } } this.advisorChainInitialized = true; }
生成单件代理对象
ProxyFactoryBean的getSingletonInstanceprivate synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { //这里会调用getBean,获取被代理对象 this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // 根据 AOP 框架判断需要代理的接口 Class<?> targetClass = getTargetClass(); if (targetClass == null) { throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy"); } //这里是设置代理对象的接口 setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } // Initialize the shared singleton instance. super.setFrozen(this.freezeProxy); //这里方法会使用ProxyFactory生成需要的Proxy this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; } //通过createAopProxy返回的AopProxy来得到代理对象 protected Object getProxy(AopProxy aopProxy) { return aopProxy.getProxy(this.proxyClassLoader); }
ProxyFactoryBean的freshTargetSource
private TargetSource freshTargetSource() { if (this.targetName == null) { if (logger.isTraceEnabled()) { logger.trace("Not refreshing target: Bean name not specified in 'interceptorNames'."); } return this.targetSource; } else { if (this.beanFactory == null) { throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " + "- cannot resolve target with name '" + this.targetName + "'"); } if (logger.isDebugEnabled()) { logger.debug("Refreshing target with name '" + this.targetName + "'"); } Object target = this.beanFactory.getBean(this.targetName); return (target instanceof TargetSource ? (TargetSource) target : new SingletonTargetSource(target)); } }
具体代理对象的生成,是在ProxyFactoryBean的基类AdvisedSupport的实现中借助AopProxyFactory完成。
在ProxyCreatorSupport中,AopProxy是通过AopProxyFactory生成的,需要生成的代理对象信息封装在AdvisedSupport中,这个对象也是createAopProxy的输入参数(this):
ProxyCreatorSupport的createAopProxy
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } //通过AopProxyFactory取得AopProxy,AopProxyFactory是在初始化函数中定义的,使用的是DefaultAopProxyFactory return getAopProxyFactory().createAopProxy(this); }
现在问题转换为DefaultAopProxyFactory如何生成AopProxy了,这里有两种方式,JdkDynamicAopProxy和CglibProxyFactory
DefaultAopProxyFactory的createAopProxy
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { //获取配置的目标对象 Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { //如果没有目标对象,抛出异常,提醒AOP应用提供正确的目标配置 throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } //由于CGLIB是一个第三方类库,所以需要在CLASSPATH中配置 return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } }
JdkDynamicAopProxy 生成AopProxy代理对象:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { @Override public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } //获取代理对象配置,主要是接口 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); //JdkDynamicAopProxy 需要实现InvocationHandler这里才能传this findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //...代理的回调方法,invoke //也可以理解为拦截方法 } }
CglibAopProxy生成AopProxy代理对象:
@Override public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource()); } try { Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); Class<?> proxySuperClass = rootClass; if (ClassUtils.isCglibProxyClass(rootClass)) { proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces(); for (Class<?> additionalInterface : additionalInterfaces) { this.advised.addInterface(additionalInterface); } } // Validate the class, writing log messages as necessary. validateClassIfNecessary(proxySuperClass, classLoader); // Configure CGLIB Enhancer... Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException ex) { throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: " + "Common causes of this problem include using a final class or a non-visible class", ex); } catch (IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.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 AopConfigException("Unexpected AOP exception", ex); } }
拦截方法写在内部类里了(在上面getCallbacks涉及到):
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable { private final AdvisedSupport advised; public DynamicAdvisedInterceptor(AdvisedSupport advised) { this.advised = advised; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; Class<?> targetClass = null; Object target = null; try { if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // May be null. Get as late as possible to minimize the time we // "own" the target, in case it comes from a pool... target = getTarget(); if (target != null) { targetClass = target.getClass(); } // 从advised中取得配置好的通知 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. // 如果没有AOP通知配置,那么直接调用target对象的调用方法 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { // We can skip creating a MethodInvocation: just invoke the target directly. // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } else { // We need to create a method invocation... // 通过CglibMethodInvocation来启动通知 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; } finally { if (target != null) { releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } } @Override public boolean equals(Object other) { return (this == other || (other instanceof DynamicAdvisedInterceptor && this.advised.equals(((DynamicAdvisedInterceptor) other).advised))); } /** * CGLIB uses this to drive proxy creation. */ @Override public int hashCode() { return this.advised.hashCode(); } protected Object getTarget() throws Exception { return this.advised.getTargetSource().getTarget(); } protected void releaseTarget(Object target) throws Exception { this.advised.getTargetSource().releaseTarget(target); } }
可以把AOP的实现部分堪称有基础设施准备和AOP运行辅助这两部分组成。
这里的AOPProxy代理对象的生成,可以看作是一个静态的AOP基础设施的建立过程。通过这个准备过程,把代理对象、拦截器这些待调用的部分都准备好,等待着AOP运行过程中对这些基础设施的使用。
对于应用触发的AOP应用,会涉及AOP框架的运行和对AOP基础设施的使用。
这些动态的运行部分,是从拦截器回调入口开始的。
相关文章推荐
- java获取指定连接上的图片并保存到本地
- Spring MVC 学习 之 - URL参数传递
- [javaSE] 集合框架(ArrayList,LinkedList,Vector)
- 用Java写脚本,常用的一些方法
- eclipse NDK jni配置
- eclipse类、方法添加作者与功能描述注释
- java第十周学习总结
- SpringMVC注解版解析不同格式的JSON串
- 自制小游戏,(根据java书进行改进的)
- java中字符串的排序(1)
- 《JAVA程序设计》第五次实验报告
- 20145316《Java程序设计》第十周学习总结
- 20145335《java程序设计》第10周学习总结
- 20145335《java程序设计》第5次实验报告
- java第五次实验报告
- 20145222黄亚奇《Java程序设计》实验五实验报告
- Spring入门之关于IOC和DI的大致启动流程
- java内存区域与内存溢出异常
- 注解方式配置的spring mvc
- 20145106java实验四