Spring AOP源码分析

男娘i 2022-01-28 11:57 332阅读 0赞

Spring AOP源码分析

核心类:AbstractAutoProxyCreator

1179709-20190415231531685-994172411.png

继续看:

1179709-20190415231718063-942829424.png

流程说明

1)AOP标签的定义解析刘彻骨肯定是从NamespaceHandlerSupport的实现类开始解析的,这个实现类就是AopNamespaceHandler。至于为什么会是从NamespaceHandlerSupport的实现类开始解析的,这个的话我想读者可以去在回去看看Spring自定义标签的解析流程,里面说的比较详细。

2)要启用AOP,我们一般会在Spring里面配置 ,所以在配置文件中在遇到aspectj-autoproxy标签的时候我们会采用AspectJAutoProxyBeanDefinitionParser解析器

3)进入AspectJAutoProxyBeanDefinitionParser解析器后,调用AspectJAutoProxyBeanDefinitionParser已覆盖BeanDefinitionParser的parser方法,然后parser方法把请求转交给了AopNamespaceUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary去处理

4)进入AopNamespaceUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法后,先调用AopConfigUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,里面在转发调用给registerOrEscalateApcAsRequired,注册或者升级AnnotationAwareAspectJAutoProxyCreator类。对于AOP的实现,基本是靠AnnotationAwareAspectJAutoProxyCreator去完成的,它可以根据@point注解定义的切点来代理相匹配的bean。

5)AopConfigUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法处理完成之后,接下来会调用useClassProxyingIfNecessary() 处理proxy-target-class以及expose-proxy属性。如果将proxy-target-class设置为true的话,那么会强制使用CGLIB代理,否则使用jdk动态代理,expose-proxy属性是为了解决有时候目标对象内部的自我调用无法实现切面增强。

6)最后的调用registerComponentIfNecessary 方法,注册组建并且通知便于监听器做进一步处理。

创建AOP代理

上面说到AOP的核心逻辑是在AnnotationAwareAspectJAutoProxyCreator类里面实现,那么我们先来看看这个类的层次关系

流程说明

1) spring 容器启动,每个bean的实例化之前都会先经过AbstractAutoProxyCreator类的postProcessAfterInitialization()这个方法,然后接下来是调用wrapIfNecessary方法。

1179709-20190415232329973-230879617.png

  1. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  2. if (bean != null) {
  3. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  4. if (!this.earlyProxyReferences.contains(cacheKey)) {
  5. return wrapIfNecessary(bean, beanName, cacheKey);
  6. }
  7. }
  8. return bean;
  9. }
  10. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  11. if (this.targetSourcedBeans.contains(beanName)) {
  12. return bean;
  13. }
  14. if (this.nonAdvisedBeans.contains(cacheKey)) {
  15. return bean;
  16. }
  17. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  18. this.nonAdvisedBeans.add(cacheKey);
  19. return bean;
  20. }
  21. // Create proxy if we have advice.
  22. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  23. if (specificInterceptors != DO_NOT_PROXY) {
  24. this.advisedBeans.add(cacheKey);
  25. Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  26. this.proxyTypes.put(cacheKey, proxy.getClass());
  27. return proxy;
  28. }
  29. this.nonAdvisedBeans.add(cacheKey);
  30. return bean;
  31. }
  32. 创建代理对象
  33. protected Object createProxy(
  34. Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
  35. ProxyFactory proxyFactory = new ProxyFactory();
  36. // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
  37. proxyFactory.copyFrom(this);
  38. if (!shouldProxyTargetClass(beanClass, beanName)) {
  39. // Must allow for introductions; can't just set interfaces to
  40. // the target's interfaces only.
  41. Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
  42. for (Class<?> targetInterface : targetInterfaces) {
  43. proxyFactory.addInterface(targetInterface);
  44. }
  45. }
  46. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  47. for (Advisor advisor : advisors) {
  48. proxyFactory.addAdvisor(advisor);
  49. }
  50. proxyFactory.setTargetSource(targetSource);
  51. customizeProxyFactory(proxyFactory);
  52. proxyFactory.setFrozen(this.freezeProxy);
  53. if (advisorsPreFiltered()) {
  54. proxyFactory.setPreFiltered(true);
  55. }
  56. return proxyFactory.getProxy(this.proxyClassLoader);
  57. }

1179709-20190415232430200-1179614118.png

posted @ 2019-04-15 23:30 toov5 阅读(…) 评论(…) 编辑 收藏

发表评论

表情:
评论列表 (有 0 条评论,332人围观)

还没有评论,来说两句吧...

相关阅读