INT-4327: Optimize Bean Post Processors
JIRA: https://jira.spring.io/browse/INT-4327 To avoid reflection and annotation processing overhead on the bean classes when we deal with non-singleton beans and there is really no any messaging on the bean class, store bean classes to the local cache to skip them in the future when `BPP` is applied for request/prototype beans * Simple code style polishing **Cherry-pick to 4.3.x**
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.integration.aop;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.framework.ProxyConfig;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
@@ -37,6 +41,8 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
* @author Rick Hogge
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
@@ -53,6 +59,9 @@ public class PublisherAnnotationBeanPostProcessor extends ProxyConfig
|
||||
|
||||
private volatile ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private final Set<Class<?>> nonApplicableCache =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>(256));
|
||||
|
||||
/**
|
||||
* Set the default channel where Messages should be sent if the annotation
|
||||
* itself does not provide a channel.
|
||||
@@ -101,6 +110,12 @@ public class PublisherAnnotationBeanPostProcessor extends ProxyConfig
|
||||
return bean;
|
||||
}
|
||||
|
||||
// the set will hold records of prior class scans and will contain the bean classes that can not
|
||||
// be assigned to the Advisor interface and therefore can be short circuited
|
||||
if (this.nonApplicableCache.contains(targetClass)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
if (AopUtils.canApply(this.advisor, targetClass)) {
|
||||
if (bean instanceof Advised) {
|
||||
((Advised) bean).addAdvisor(this.advisor);
|
||||
@@ -116,6 +131,7 @@ public class PublisherAnnotationBeanPostProcessor extends ProxyConfig
|
||||
}
|
||||
else {
|
||||
// cannot apply advisor
|
||||
nonApplicableCache.add(targetClass);
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -71,6 +72,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Marius Bogoevici
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
* @author Rick Hogge
|
||||
*/
|
||||
public class MessagingAnnotationPostProcessor implements BeanPostProcessor, BeanFactoryAware,
|
||||
InitializingBean, SmartInitializingSingleton {
|
||||
@@ -84,6 +86,8 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private final Set<Class<?>> noAnnotationsCache =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>(256));
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
@@ -151,6 +155,11 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
|
||||
|
||||
Class<?> beanClass = AopUtils.getTargetClass(bean);
|
||||
|
||||
// the set will hold records of prior class scans and indicate if no messaging annotations were found
|
||||
if (this.noAnnotationsCache.contains(beanClass)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
ReflectionUtils.doWithMethods(beanClass, method -> {
|
||||
Map<Class<? extends Annotation>, List<Annotation>> annotationChains = new HashMap<>();
|
||||
for (Class<? extends Annotation> annotationType :
|
||||
@@ -168,6 +177,10 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
|
||||
List<Annotation> annotations = entry.getValue();
|
||||
processAnnotationTypeOnMethod(bean, beanName, method, annotationType, annotations);
|
||||
}
|
||||
|
||||
if (annotationChains.size() == 0) {
|
||||
noAnnotationsCache.add(beanClass);
|
||||
}
|
||||
}, ReflectionUtils.USER_DECLARED_METHODS);
|
||||
|
||||
return bean;
|
||||
|
||||
Reference in New Issue
Block a user