diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index 98bce815435..5dee5d1e23c 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import java.util.concurrent.ScheduledExecutorService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.aop.framework.AopProxyUtils; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -311,7 +312,7 @@ public class ScheduledAnnotationBeanPostProcessor @Override public Object postProcessAfterInitialization(final Object bean, String beanName) { - Class targetClass = AopUtils.getTargetClass(bean); + Class targetClass = AopProxyUtils.ultimateTargetClass(bean); if (!this.nonAnnotatedClasses.contains(targetClass)) { Map> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup>) method -> { diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java index 3e7fe5e5d3e..9b262718b63 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import java.util.TimeZone; import org.junit.After; import org.junit.Test; +import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.BeanDefinition; @@ -179,6 +180,14 @@ public class ScheduledAnnotationBeanPostProcessorTests { severalFixedRates(context, processorDefinition, targetDefinition); } + @Test + public void severalFixedRatesAgainstNestedCglibProxy() { + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition(SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean.class); + targetDefinition.setFactoryMethodName("nestedProxy"); + severalFixedRates(context, processorDefinition, targetDefinition); + } + private void severalFixedRates(StaticApplicationContext context, BeanDefinition processorDefinition, BeanDefinition targetDefinition) { @@ -631,6 +640,14 @@ public class ScheduledAnnotationBeanPostProcessorTests { @Scheduled(fixedRate = 4000, initialDelay = 2000) public void fixedRate() { } + + static SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean nestedProxy() { + ProxyFactory pf1 = new ProxyFactory(new SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean()); + pf1.setProxyTargetClass(true); + ProxyFactory pf2 = new ProxyFactory(pf1.getProxy()); + pf2.setProxyTargetClass(true); + return (SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean) pf2.getProxy(); + } }