spring 源码探索 -- aop 标签解析和创建代理
2016-12-23 01:00
801 查看
aopNamespaceHandler
aop标签和相应的aop parser映射在一起。注册 AspectJAnnotationAutoProxyCreator
AspectJAutoProxyBeanDefinitionParserparser方法实现注册。
AspectJAnnotationAutoProxyCreator的流程
AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator 是一个BeanPostProcessor实现,它注册的时机是在
AbstractApplicationContext的
registerBeanPostProcessors里面。这个方法会注册spring 容器所有BeanPostProcessor接口的实例。
调用postProcessBeforeInstantiation或者postProcessAfterInitialization
获取增强器 所有的增强器在增强类的方法上查找aop注解
/** * Find and return the first AspectJ annotation on the given method * (there <i>should</i> only be one anyway...) */ @SuppressWarnings("unchecked") protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { Class<?>[] classesToLookFor = new Class<?>[] { Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}; for (Class<?> c : classesToLookFor) { AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c); if (foundAnnotation != null) { return foundAnnotation; } } return null; }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Before { }
对于不同的增强处理(before,after…),创建不同的实例。
before AspectJMethodBeforeAdvice
使用了MethodBeforeAdviceInterceptor做拦截器,先调用自己的invoke方法,然后再调用真正before的方法
after AspectJAfterAdvice 不一样,直接调用invoke方法。
try { return mi.proceed(); } finally { invokeAdviceMethod(getJoinPointMatch(), null, null); }
寻找匹配的增强器
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); if (!pc.getClassFilter().matches(targetClass)) { return false; } MethodMatcher methodMatcher = pc.getMethodMatcher(); IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); for (Class<?> clazz : classes) { Method[] methods = clazz.getMethods(); for (Method method : methods) { if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || methodMatcher.matches(method, targetClass)) { return true; } } } return false; }
创建代理
上面的步骤找到了与当前bean匹配的增强器,specificInterceptors,下一步就要开始创建代理了。从默认aop代理工厂DefaultAopProxyFactory中,根据不同的代理策略来创建aop代理,这里还没有创建代理bean
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface()) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
使用工厂模式创建aop代理
JdkDynamicAopProxy
典型的jdk 动态代理模式.构造函数传入目标对象,这里是AdvisedSupport 实例
getProxy
invoke 先获取当前方法的拦截器链,使用
ReflectiveMethodInvocation封装拦截器链,然后一个个调用。
invocation.proceed();方法中就是调用增强的方法和目标方法。
if (chain.isEmpty()) { // 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. retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } else { // We need to create a method invocation... invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed(); }
CGLIB 代理
典型实现Enhancer.setCallback(MethodInterceptorImpl) 在这里设置拦截器,
Enhancer.create生成代理。
MethodInterceptorImpl 中
proxy.invokeSuper(obj.args)
aop实现
getCallbacks(Class...)获取拦截器。
将拦截器封装在
DynamicAdvisedInterceptor中,该类的intercept方法负责处理拦截器的调用,处理的方式和jdk代理中的invoke很类似。
参考:http://www.jianshu.com/p/867991f3daa0
相关文章推荐
- SpringAOP源码解析之代理创建篇
- Spring源码阅读4.2-Aspecjt AOP之代理对象的创建
- Spring AOP源码解析——AOP动态代理原理和实现方式
- spring 源码探索--xml的默认标签解析
- Spring Framework源码(六):Spring AOP之解析标签
- Spring AOP 源码分析——创建代理对象
- Spring AOP高级——源码实现(3)AopProxy代理对象之JDK动态代理的创建过程
- Spring 源码分析(三) —— AOP(五)创建代理
- Spring AOP 源码分析 - 创建代理对象
- spring 源码探索--xml的自定义标签解析
- 【Spring源码--AOP的实现】(一)AopProxy代理对象的创建
- Spring源码之创建AOP代理(补)
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-使用工厂创建代理(Using the ProxyFactoryObject to create AOP proxies)
- 做一个合格的程序猿之浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理
- (八)Spring核心框架 - AOP的原理及源码解析
- spring 代理对象方法增强源码解析
- 杨老师课堂之springAOP事务控制源码解析
- spring源码解析-Aop
- Spring AOP 自动创建代理
- spring-aop源码解析:declare-parent