@Test
  public void testAutoProxyCreatorWithFactoryBeanAndProxyFactoryBeanOnly() {
    StaticApplicationContext sac = new StaticApplicationContext();

    MutablePropertyValues pvs = new MutablePropertyValues();
    pvs.add("proxyObject", "false");
    sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class, pvs);

    pvs = new MutablePropertyValues();
    pvs.add("singleton", "false");
    sac.registerSingleton("prototypeFactoryToBeProxied", DummyFactory.class, pvs);

    sac.refresh();

    TestAutoProxyCreator tapc = (TestAutoProxyCreator) sac.getBean("testAutoProxyCreator");
    tapc.testInterceptor.nrOfInvocations = 0;

    FactoryBean<?> prototypeFactory = (FactoryBean<?>) sac.getBean("&prototypeFactoryToBeProxied");
    assertTrue(AopUtils.isCglibProxy(prototypeFactory));
    TestBean tb = (TestBean) sac.getBean("prototypeFactoryToBeProxied");
    assertFalse(AopUtils.isCglibProxy(tb));

    assertEquals(2, tapc.testInterceptor.nrOfInvocations);
    tb.getAge();
    assertEquals(2, tapc.testInterceptor.nrOfInvocations);
  }
  @Test
  public void testCustomAutoProxyCreator() {
    StaticApplicationContext sac = new StaticApplicationContext();
    sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class);
    sac.registerSingleton("singletonNoInterceptor", TestBean.class);
    sac.registerSingleton("singletonToBeProxied", TestBean.class);
    sac.registerPrototype("prototypeToBeProxied", TestBean.class);
    sac.refresh();

    MessageSource messageSource = (MessageSource) sac.getBean("messageSource");
    ITestBean singletonNoInterceptor = (ITestBean) sac.getBean("singletonNoInterceptor");
    ITestBean singletonToBeProxied = (ITestBean) sac.getBean("singletonToBeProxied");
    ITestBean prototypeToBeProxied = (ITestBean) sac.getBean("prototypeToBeProxied");
    assertFalse(AopUtils.isCglibProxy(messageSource));
    assertTrue(AopUtils.isCglibProxy(singletonNoInterceptor));
    assertTrue(AopUtils.isCglibProxy(singletonToBeProxied));
    assertTrue(AopUtils.isCglibProxy(prototypeToBeProxied));

    TestAutoProxyCreator tapc = (TestAutoProxyCreator) sac.getBean("testAutoProxyCreator");
    assertEquals(0, tapc.testInterceptor.nrOfInvocations);
    singletonNoInterceptor.getName();
    assertEquals(0, tapc.testInterceptor.nrOfInvocations);
    singletonToBeProxied.getAge();
    assertEquals(1, tapc.testInterceptor.nrOfInvocations);
    prototypeToBeProxied.getSpouse();
    assertEquals(2, tapc.testInterceptor.nrOfInvocations);
  }
 private Class<?> getTargetClass(Object targetObject) {
   Class<?> targetClass = targetObject.getClass();
   if (AopUtils.isAopProxy(targetObject)) {
     targetClass = AopUtils.getTargetClass(targetObject);
     if (targetClass == targetObject.getClass()) {
       try {
         // Maybe a proxy with no target - e.g. gateway
         Class<?>[] interfaces = ((Advised) targetObject).getProxiedInterfaces();
         if (interfaces != null && interfaces.length == 1) {
           targetClass = interfaces[0];
         }
       } catch (Exception e) {
         if (logger.isDebugEnabled()) {
           logger.debug("Exception trying to extract interface", e);
         }
       }
     }
   } else if (org.springframework.util.ClassUtils.isCglibProxyClass(targetClass)) {
     Class<?> superClass = targetObject.getClass().getSuperclass();
     if (!Object.class.equals(superClass)) {
       targetClass = superClass;
     }
   }
   return targetClass;
 }
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof AopInfrastructureBean) {
      // Ignore AOP infrastructure such as scoped proxies.
      return bean;
    }

    Class<?> targetClass = AopUtils.getTargetClass(bean);
    if (targetClass == null) {
      // Can't do much here.
      return bean;
    }

    if (AopUtils.canApply(this.asyncAnnotationAdvisor, targetClass)) {
      if (bean instanceof Advised) {
        ((Advised) bean).addAdvisor(this.asyncAnnotationAdvisor);
        return bean;
      } else {
        ProxyFactory proxyFactory = new ProxyFactory(bean);
        // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
        proxyFactory.copyFrom(this);
        proxyFactory.addAdvisor(this.asyncAnnotationAdvisor);
        return proxyFactory.getProxy(this.beanClassLoader);
      }
    } else {
      // No async proxy needed.
      return bean;
    }
  }
  @Test
  public void testGetAnonymousInnerBeanFromScope() throws Exception {
    TestBean bean = (TestBean) this.beanFactory.getBean("outerBean");
    assertFalse(AopUtils.isAopProxy(bean));
    assertTrue(AopUtils.isCglibProxy(bean.getSpouse()));

    BeanDefinition beanDef = this.beanFactory.getBeanDefinition("outerBean");
    BeanDefinitionHolder innerBeanDef =
        (BeanDefinitionHolder) beanDef.getPropertyValues().getPropertyValue("spouse").getValue();
    String name = innerBeanDef.getBeanName();

    MockHttpServletRequest request = new MockHttpServletRequest();
    RequestAttributes requestAttributes = new ServletRequestAttributes(request);
    RequestContextHolder.setRequestAttributes(requestAttributes);

    try {
      assertNull(request.getAttribute("scopedTarget." + name));
      assertEquals("scoped", bean.getSpouse().getName());
      assertNotNull(request.getAttribute("scopedTarget." + name));
      assertEquals(TestBean.class, request.getAttribute("scopedTarget." + name).getClass());
      assertEquals("scoped", ((TestBean) request.getAttribute("scopedTarget." + name)).getName());
    } finally {
      RequestContextHolder.setRequestAttributes(null);
    }
  }
  public static Class<?> getGenericTypeFromBean(Object object) {
    Class<?> clazz = object.getClass();

    if (AopUtils.isAopProxy(object)) {
      clazz = AopUtils.getTargetClass(object);
    }
    return getGenericType(clazz);
  }
 /**
  * 获取目标对象.
  *
  * @param proxy 代理对象
  * @return 目标对象
  */
 public static Object getTarget(final Object proxy) {
   if (!AopUtils.isAopProxy(proxy)) {
     return proxy;
   }
   if (AopUtils.isJdkDynamicProxy(proxy)) {
     return getProxyTargetObject(proxy, "h");
   } else {
     return getProxyTargetObject(proxy, "CGLIB$CALLBACK_0");
   }
 }
  /**
   * 获取 目标对象
   *
   * @param proxy 代理对象
   * @return
   * @throws Exception
   */
  public static Object getTarget(Object proxy) throws Exception {
    if (!AopUtils.isAopProxy(proxy)) {
      return proxy; // 不是代理对象
    }

    if (AopUtils.isJdkDynamicProxy(proxy)) {
      return getJdkDynamicProxyTargetObject(proxy);
    } else { // cglib
      return getCglibProxyTargetObject(proxy);
    }
  }
  /** {@InheritDoc} */
  @Override
  public List<BeanDetail> getBeanDetails() {

    if (this.allBeans == null) {

      // initialize BeanDetail list
      List<BeanDetail> beans = new ArrayList<BeanDetail>();
      BeanDetail springBeanDetail;

      // get the list of bean names
      List<String> names = this.getBeanNames();

      for (String beanName : names) {
        springBeanDetail = new BeanDetail();
        springBeanDetail.setBeanName(beanName);

        Object bean;
        String beanType;

        springBeanDetail.setAliases(Arrays.asList(this.ctx.getAliases(beanName)));
        bean = this.ctx.getBean(beanName);
        beanType = bean.getClass().getName();

        // Manage proxied beans
        // If the bean is proxied then its type is modiified. We
        // detect
        // it and get the correct target type
        if (AopUtils.isAopProxy(bean)) {
          beanType = AopUtils.getTargetClass(bean).getName();
          springBeanDetail.setProxied(true);
        }

        springBeanDetail.setBeanType(beanType);
        springBeanDetail.setPrototype(this.ctx.isPrototype(beanName));
        springBeanDetail.setSingleton(this.ctx.isSingleton(beanName));
        springBeanDetail.setBean(this.ctx.getBean(beanName));

        if (this.configurablebeanFactory != null) {

          BeanDefinition beanDefinition = this.configurablebeanFactory.getBeanDefinition(beanName);
          springBeanDetail.setBeanType(beanDefinition.getBeanClassName());
          springBeanDetail.setDescription(beanDefinition.getDescription());
          springBeanDetail.setScope(beanDefinition.getScope());
          springBeanDetail.setLazyInit(beanDefinition.isLazyInit());
          springBeanDetail.setAbstract(beanDefinition.isAbstract());
        }
        beans.add(springBeanDetail);
      }
      this.allBeans = beans;
    }

    return this.allBeans;
  }
  @Override
  public Object postProcessAfterInitialization(final Object bean, final String beanName)
      throws BeansException {
    Class<?> targetClass = AopUtils.getTargetClass(bean);
    final RabbitListener classLevelListener =
        AnnotationUtils.findAnnotation(bean.getClass(), RabbitListener.class);
    final List<Method> multiMethods = new ArrayList<Method>();
    ReflectionUtils.doWithMethods(
        targetClass,
        new ReflectionUtils.MethodCallback() {

          @Override
          public void doWith(Method method)
              throws IllegalArgumentException, IllegalAccessException {
            RabbitListener rabbitListener =
                AnnotationUtils.getAnnotation(method, RabbitListener.class);
            if (rabbitListener != null) {
              processAmqpListener(rabbitListener, method, bean, beanName);
            }
            if (classLevelListener != null) {
              RabbitHandler rabbitHandler =
                  AnnotationUtils.getAnnotation(method, RabbitHandler.class);
              if (rabbitHandler != null) {
                multiMethods.add(method);
              }
            }
          }
        });
    if (classLevelListener != null) {
      processMultiMethodListener(classLevelListener, multiMethods, bean, beanName);
    }
    return bean;
  }
 private void prepareEvaluationContext(
     StandardEvaluationContext context,
     Object method,
     Class<? extends Annotation> annotationType) {
   Class<?> targetType = AopUtils.getTargetClass(this.targetObject);
   if (method instanceof Method) {
     context.registerMethodFilter(targetType, new FixedMethodFilter((Method) method));
     if (expectedType != null) {
       Assert.state(
           context
               .getTypeConverter()
               .canConvert(
                   TypeDescriptor.valueOf(((Method) method).getReturnType()),
                   TypeDescriptor.valueOf(expectedType)),
           "Cannot convert to expected type (" + expectedType + ") from " + method);
     }
   } else if (method == null || method instanceof String) {
     AnnotatedMethodFilter filter =
         new AnnotatedMethodFilter(annotationType, (String) method, this.requiresReply);
     Assert.state(
         canReturnExpectedType(filter, targetType, context.getTypeConverter()),
         "Cannot convert to expected type (" + expectedType + ") from " + method);
     context.registerMethodFilter(targetType, filter);
   }
   context.setVariable("target", targetObject);
 }
 /**
  * Throws an IllegalArgumentException if it encounters a JDK dynamic proxy. Metadata can only be
  * read from target classes and CGLIB proxies!
  */
 protected void checkManagedBean(Object managedBean) throws IllegalArgumentException {
   if (AopUtils.isJdkDynamicProxy(managedBean)) {
     throw new IllegalArgumentException(
         "MetadataMBeanInfoAssembler does not support JDK dynamic proxies - "
             + "export the target beans directly or use CGLIB proxies instead");
   }
 }
 @Override
 public Object postProcessAfterInitialization(final Object bean, String beanName) {
   if (!this.nonAnnotatedClasses.contains(bean.getClass())) {
     final Set<Method> annotatedMethods = new LinkedHashSet<Method>(1);
     Class<?> targetClass = AopUtils.getTargetClass(bean);
     ReflectionUtils.doWithMethods(
         targetClass,
         new MethodCallback() {
           @Override
           public void doWith(Method method)
               throws IllegalArgumentException, IllegalAccessException {
             for (Scheduled scheduled :
                 AnnotationUtils.getRepeatableAnnotation(
                     method, Schedules.class, Scheduled.class)) {
               processScheduled(scheduled, method, bean);
               annotatedMethods.add(method);
             }
           }
         });
     if (annotatedMethods.isEmpty()) {
       this.nonAnnotatedClasses.add(bean.getClass());
     }
   }
   return bean;
 }
  @Test
  public void withCglibProxy() {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithCglibProxy.class);

    aspectIsApplied(ctx);
    assertThat(AopUtils.isCglibProxy(ctx.getBean(FooService.class)), is(true));
  }
  @Override
  public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
    checkReadyToMatch();
    Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
    ShadowMatch shadowMatch = getShadowMatch(targetMethod, method);

    // Special handling for this, target, @this, @target, @annotation
    // in Spring - we can optimize since we know we have exactly this class,
    // and there will never be matching subclass at runtime.
    if (shadowMatch.alwaysMatches()) {
      return true;
    } else if (shadowMatch.neverMatches()) {
      return false;
    } else {
      // the maybe case
      if (beanHasIntroductions) {
        return true;
      }
      // A match test returned maybe - if there are any subtype sensitive variables
      // involved in the test (this, target, at_this, at_target, at_annotation) then
      // we say this is not a match as in Spring there will never be a different
      // runtime subtype.
      RuntimeTestWalker walker = getRuntimeTestWalker(shadowMatch);
      return (!walker.testsSubtypeSensitiveVars()
          || walker.testTargetInstanceOfResidue(targetClass));
    }
  }
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    Method[] methods = AopUtils.getTargetClass(bean).getDeclaredMethods();
    for (Method method : methods) {
      if (method.isAnnotationPresent(MethodLimiter.class)) {
        MethodLimiter methodLimiter = method.getAnnotation(MethodLimiter.class);
        // 获取zkclient
        ZKClusterClient client =
            ZookeeperClientMakerFactory.getInstance().getZKClusterClient("zkClient");
        String name = methodLimiter.name();
        int rate = methodLimiter.rate();
        // 创建rateLimiter
        RateLimiterFactory.getInstance().putIfAbsent(name, new RateLimiter().create(name, rate));
        String path = PATH_PREFIX + "/" + name;
        if (!client.isExsit(path)) {
          // 创建节点
          client.createNode(
              path, String.valueOf(rate), com.foxxy.git.zookeeper.CreateMode.PERSISTENT);
        }
        client.registerConnectionListener(new LimiterRateMonitorListener(path));

        client.registerNodeListener(path, new LimiterRateMonitorListener(path));
      }
    }
    return bean;
  }
  /**
   * Intercept the given method invocation, submit the actual calling of the method to the correct
   * task executor and return immediately to the caller.
   *
   * @param invocation the method to intercept and make asynchronous
   * @return {@link Future} if the original method returns {@code Future}; {@code null} otherwise.
   */
  public Object invoke(final MethodInvocation invocation) throws Throwable {
    Class<?> targetClass =
        (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
    specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

    Future<?> result =
        determineAsyncExecutor(specificMethod)
            .submit(
                new Callable<Object>() {
                  public Object call() throws Exception {
                    try {
                      Object result = invocation.proceed();
                      if (result instanceof Future) {
                        return ((Future<?>) result).get();
                      }
                    } catch (Throwable ex) {
                      ReflectionUtils.rethrowException(ex);
                    }
                    return null;
                  }
                });

    if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) {
      return result;
    } else {
      return null;
    }
  }
  protected void loadArgsAsVariables() {
    // shortcut if no args need to be loaded
    if (ObjectUtils.isEmpty(args)) {
      return;
    }

    String key = toString(method);
    Method targetMethod = methodCache.get(key);
    if (targetMethod == null) {
      targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
      if (targetMethod == null) {
        targetMethod = method;
      }
      methodCache.put(key, targetMethod);
    }

    // save arguments as indexed variables
    for (int i = 0; i < args.length; i++) {
      setVariable("p" + i, args[i]);
    }

    String[] parameterNames = paramDiscoverer.getParameterNames(targetMethod);
    // save parameter names (if discovered)
    if (parameterNames != null) {
      for (int i = 0; i < parameterNames.length; i++) {
        setVariable(parameterNames[i], args[i]);
      }
    }
  }
 @Test
 public void testImportXmlWithNamespaceConfig() {
   AnnotationConfigApplicationContext ctx =
       new AnnotationConfigApplicationContext(ImportXmlWithAopNamespaceConfig.class);
   Object bean = ctx.getBean("proxiedXmlBean");
   assertTrue(AopUtils.isAopProxy(bean));
 }
 private Map<String, Object> getHandlerMap(AbstractUrlHandlerMapping mapping) {
   if (AopUtils.isCglibProxy(mapping)) {
     // If the AbstractUrlHandlerMapping is a cglib proxy we can't call
     // the final getHandlerMap() method.
     return Collections.emptyMap();
   }
   return mapping.getHandlerMap();
 }
 @SuppressWarnings({"unchecked"})
 private <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception {
   if (AopUtils.isJdkDynamicProxy(proxy)) {
     return (T) ((Advised) proxy).getTargetSource().getTarget();
   } else {
     return (T) proxy;
   }
 }
 /**
  * Finds any {@link #equals} or {@link #hashCode} method that may be defined on the supplied set
  * of interfaces.
  *
  * @param proxiedInterfaces the interfaces to introspect
  */
 private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) {
   for (int i = 0; i < proxiedInterfaces.length; i++) {
     Class proxiedInterface = proxiedInterfaces[i];
     Method[] methods = proxiedInterface.getDeclaredMethods();
     for (int j = 0; j < methods.length; j++) {
       Method method = methods[j];
       if (AopUtils.isEqualsMethod(method)) {
         this.equalsDefined = true;
       }
       if (AopUtils.isHashCodeMethod(method)) {
         this.hashCodeDefined = true;
       }
       if (this.equalsDefined && this.hashCodeDefined) {
         return;
       }
     }
   }
 }
 @Test
 public void annotatedService_PTC_true() {
   AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
   ctx.register(PTCTrue.class, NonAnnotatedServiceImpl.class);
   ctx.refresh();
   AnnotatedService s = ctx.getBean(AnnotatedService.class);
   assertTrue("expected a subclass proxy", AopUtils.isCglibProxy(s));
   assertThat(s, instanceOf(NonAnnotatedServiceImpl.class));
 }
 @Test
 public void annotatedService_PTC_false() {
   AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
   ctx.register(PTCFalse.class, NonAnnotatedServiceImpl.class);
   ctx.refresh();
   AnnotatedService s = ctx.getBean(AnnotatedService.class);
   assertTrue("expected a jdk proxy", AopUtils.isJdkDynamicProxy(s));
   assertThat(s, not(instanceOf(NonAnnotatedServiceImpl.class)));
 }
 private Object applyAdvice(Object bean, PointcutAdvisor advisor, ClassLoader beanClassLoader) {
   Class<?> targetClass = AopUtils.getTargetClass(bean);
   if (AopUtils.canApply(advisor.getPointcut(), targetClass)) {
     if (bean instanceof Advised) {
       ((Advised) bean).addAdvisor(advisor);
       return bean;
     } else {
       ProxyFactory proxyFactory = new ProxyFactory(bean);
       proxyFactory.addAdvisor(advisor);
       /**
        * N.B. it's not a good idea to use proxyFactory.setProxyTargetClass(true) here because it
        * forces all the integration components to be cglib proxyable (i.e. have a default
        * constructor etc.), which they are not in general (usually for good reason).
        */
       return proxyFactory.getProxy(beanClassLoader);
     }
   }
   return bean;
 }
 @Test
 public void transactionProxyIsCreated() {
   AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
   ctx.register(EnableTxConfig.class, TxManagerConfig.class);
   ctx.refresh();
   TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class);
   assertThat("testBean is not a proxy", AopUtils.isAopProxy(bean), is(true));
   Map<?, ?> services = ctx.getBeansWithAnnotation(Service.class);
   assertThat("Stereotype annotation not visible", services.containsKey("testBean"), is(true));
 }
  @Test
  public void testAutoProxyCreatorWithFactoryBean() {
    StaticApplicationContext sac = new StaticApplicationContext();
    sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class);
    sac.registerSingleton("singletonFactoryToBeProxied", DummyFactory.class);
    sac.refresh();

    TestAutoProxyCreator tapc = (TestAutoProxyCreator) sac.getBean("testAutoProxyCreator");
    tapc.testInterceptor.nrOfInvocations = 0;

    FactoryBean<?> factory = (FactoryBean<?>) sac.getBean("&singletonFactoryToBeProxied");
    assertTrue(AopUtils.isCglibProxy(factory));

    TestBean tb = (TestBean) sac.getBean("singletonFactoryToBeProxied");
    assertTrue(AopUtils.isCglibProxy(tb));
    assertEquals(2, tapc.testInterceptor.nrOfInvocations);
    tb.getAge();
    assertEquals(3, tapc.testInterceptor.nrOfInvocations);
  }
  @Test
  public void proxyingOccurs() {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(AsyncConfig.class);
    ctx.refresh();

    AsyncBean asyncBean = ctx.getBean(AsyncBean.class);
    assertThat(AopUtils.isAopProxy(asyncBean), is(true));
    asyncBean.work();
  }
  /**
   * Apply the given AOP method invocation to the given {@link RmiInvocationHandler}.
   *
   * <p>The default implementation delegates to {@link #createRemoteInvocation}.
   *
   * @param methodInvocation the current AOP method invocation
   * @param invocationHandler the RmiInvocationHandler to apply the invocation to
   * @return the invocation result
   * @throws RemoteException in case of communication errors
   * @throws NoSuchMethodException if the method name could not be resolved
   * @throws IllegalAccessException if the method could not be accessed
   * @throws InvocationTargetException if the method invocation resulted in an exception
   * @see org.springframework.remoting.support.RemoteInvocation
   */
  protected Object doInvoke(
      MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler)
      throws RemoteException, NoSuchMethodException, IllegalAccessException,
          InvocationTargetException {

    if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
      return "RMI invoker proxy for service URL [" + getJndiName() + "]";
    }

    return invocationHandler.invoke(createRemoteInvocation(methodInvocation));
  }
 @Test
 public void withScopedProxyThroughAspectJPattern() throws IOException, ClassNotFoundException {
   AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
   ctx.register(ComponentScanWithScopedProxyThroughAspectJPattern.class);
   ctx.getBeanFactory().registerScope("myScope", new SimpleMapScope());
   ctx.refresh();
   // should cast to the interface
   FooService bean = (FooService) ctx.getBean("scopedProxyTestBean");
   // should be dynamic proxy
   assertThat(AopUtils.isJdkDynamicProxy(bean), is(true));
 }