Skip to content

Commit a73d9bb

Browse files
committed
Scheduled/JmsAnnotationBeanPostProcessor properly deals with nested proxies
Issue: SPR-16196
1 parent c1bc74c commit a73d9bb

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@
3232
import org.apache.commons.logging.Log;
3333
import org.apache.commons.logging.LogFactory;
3434

35+
import org.springframework.aop.framework.AopProxyUtils;
3536
import org.springframework.aop.support.AopUtils;
3637
import org.springframework.beans.factory.BeanFactory;
3738
import org.springframework.beans.factory.BeanFactoryAware;
@@ -306,7 +307,7 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) {
306307

307308
@Override
308309
public Object postProcessAfterInitialization(final Object bean, String beanName) {
309-
Class<?> targetClass = AopUtils.getTargetClass(bean);
310+
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
310311
if (!this.nonAnnotatedClasses.contains(targetClass)) {
311312
Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
312313
new MethodIntrospector.MetadataLookup<Set<Scheduled>>() {

spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@
3333
import org.junit.After;
3434
import org.junit.Test;
3535

36+
import org.springframework.aop.framework.ProxyFactory;
3637
import org.springframework.beans.DirectFieldAccessor;
3738
import org.springframework.beans.factory.BeanCreationException;
3839
import org.springframework.beans.factory.config.BeanDefinition;
@@ -179,6 +180,14 @@ public void severalFixedRatesOnDefaultMethod() {
179180
severalFixedRates(context, processorDefinition, targetDefinition);
180181
}
181182

183+
@Test
184+
public void severalFixedRatesAgainstNestedCglibProxy() {
185+
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
186+
BeanDefinition targetDefinition = new RootBeanDefinition(SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean.class);
187+
targetDefinition.setFactoryMethodName("nestedProxy");
188+
severalFixedRates(context, processorDefinition, targetDefinition);
189+
}
190+
182191
private void severalFixedRates(StaticApplicationContext context,
183192
BeanDefinition processorDefinition, BeanDefinition targetDefinition) {
184193

@@ -486,7 +495,7 @@ public void expressionWithCron() {
486495
BeanDefinition targetDefinition = new RootBeanDefinition(ExpressionWithCronTestBean.class);
487496
context.registerBeanDefinition("postProcessor", processorDefinition);
488497
context.registerBeanDefinition("target", targetDefinition);
489-
Map<String, String> schedules = new HashMap<String, String>();
498+
Map<String, String> schedules = new HashMap<>();
490499
schedules.put("businessHours", businessHoursCronExpression);
491500
context.getBeanFactory().registerSingleton("schedules", schedules);
492501
context.refresh();
@@ -631,6 +640,14 @@ static class SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean {
631640
@Scheduled(fixedRate = 4000, initialDelay = 2000)
632641
public void fixedRate() {
633642
}
643+
644+
static SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean nestedProxy() {
645+
ProxyFactory pf1 = new ProxyFactory(new SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean());
646+
pf1.setProxyTargetClass(true);
647+
ProxyFactory pf2 = new ProxyFactory(pf1.getProxy());
648+
pf2.setProxyTargetClass(true);
649+
return (SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean) pf2.getProxy();
650+
}
634651
}
635652

636653

spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
2828
import org.apache.commons.logging.Log;
2929
import org.apache.commons.logging.LogFactory;
3030

31+
import org.springframework.aop.framework.AopProxyUtils;
3132
import org.springframework.aop.support.AopUtils;
3233
import org.springframework.beans.BeansException;
3334
import org.springframework.beans.factory.BeanFactory;
@@ -215,7 +216,7 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
215216
@Override
216217
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
217218
if (!this.nonAnnotatedClasses.contains(bean.getClass())) {
218-
Class<?> targetClass = AopUtils.getTargetClass(bean);
219+
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
219220
Map<Method, Set<JmsListener>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
220221
new MethodIntrospector.MetadataLookup<Set<JmsListener>>() {
221222
@Override

0 commit comments

Comments
 (0)