上面找到了AOP入口的位置,那么接下来就需要判断对象是否需要AOP增强。
    判断过程:
    wrapIfNecessary 判断是否需要对目标对象设置代理对象,不需要的话直接返回原始对象即可:

    1. 首先从 targetSourcedBeans 缓存中判断,如果包含目标对象的话,就返回了;
    2. 从 advisedBeans 缓存()中判断,如果不需要代理的话也直接返回了;
    3. 判断是否为 AOP 相关接口的实现类(Pointcut、Advice、Advisor),这些不需要代理;
    4. 获取增强用的拦截器们;如果为空的话,那说明也不需要代理;
    5. 那么上面的条件都符合了,就进入createProxy 先创建代理工厂阶段; :::success 缓存:
      // 存放自定义代理对象
      private final Set targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
      // 存放基础设施类比如:Pointcut、Advice、Advisor
      private final Map advisedBeans = new ConcurrentHashMap<>(256); :::

    具体源码:

    1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    2. // 判断名称不为空,并且代理对象已经存在,那么直接返回
    3. // targetSourcedBeans 在createBean阶段中的 resolveBeforeInstantiation 可能被处理
    4. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    5. return bean;
    6. }
    7. // 根据缓存(不需要代理的bean的集合)判断
    8. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    9. return bean;
    10. }
    11. // 如果是基础设施类(Pointcut、Advice、Advisor 等接口的实现类);或是应该跳过的类,则不成代理
    12. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    13. this.advisedBeans.put(cacheKey, Boolean.FALSE);
    14. return bean;
    15. }
    16. // Create proxy if we have advice.
    17. // 获取方法的拦截代理对象
    18. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    19. if (specificInterceptors != DO_NOT_PROXY) {
    20. // bean加入缓存,表示已代理
    21. this.advisedBeans.put(cacheKey, Boolean.TRUE);
    22. /*
    23. 创建代理对象
    24. bean.getClass():被代理对象的Class对象
    25. beanName:被代理对象名称
    26. specificInterceptors:被代理对象方法的增强方法
    27. new SingletonTargetSource(bean):被代理对象
    28. */
    29. Object proxy = createProxy(
    30. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    31. // 添加缓存
    32. this.proxyTypes.put(cacheKey, proxy.getClass());
    33. return proxy;
    34. }
    35. // 如果没有方法的拦截代理对象,那么加入缓存表示不需要代理
    36. this.advisedBeans.put(cacheKey, Boolean.FALSE);
    37. return bean;
    38. }