Permalink
Browse files

DefaultSingletonBeanRegistry avoids singletonObjects lock wherever po…

…ssible for non-singleton factory performance

Issue: SPR-9819
  • Loading branch information...
1 parent c24825c commit 0a3ea42fe137c9843c2a4111590d3c741a3e3eb5 @jhoeller jhoeller committed Nov 8, 2012
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2002-2012 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.aop.framework;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.aop.Advisor;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.core.Ordered;
+import org.springframework.util.ClassUtils;
+
+/**
+ * Base class for {@link BeanPostProcessor} implementations that apply a
+ * Spring AOP {@link Advisor} to specific beans.
+ *
+ * @author Juergen Hoeller
+ * @since 3.2
+ */
+public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
+ implements BeanPostProcessor, BeanClassLoaderAware, Ordered {
+
+ protected Advisor advisor;
+
+ private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
+
+ /**
+ * This should run after all other post-processors, so that it can just add
+ * an advisor to existing proxies rather than double-proxy.
+ */
+ private int order = Ordered.LOWEST_PRECEDENCE;
+
+ private final Map<String, Boolean> eligibleBeans = new ConcurrentHashMap<String, Boolean>();
+
+
+ public void setBeanClassLoader(ClassLoader beanClassLoader) {
+ this.beanClassLoader = beanClassLoader;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ public int getOrder() {
+ return this.order;
+ }
+
+
+ public Object postProcessBeforeInitialization(Object bean, String beanName) {
+ return bean;
+ }
+
+ public Object postProcessAfterInitialization(Object bean, String beanName) {
+ if (bean instanceof AopInfrastructureBean) {
+ // Ignore AOP infrastructure such as scoped proxies.
+ return bean;
+ }
+ if (isEligible(bean, beanName)) {
+ if (bean instanceof Advised) {
+ ((Advised) bean).addAdvisor(0, this.advisor);
+ return bean;
+ }
+ else {
+ ProxyFactory proxyFactory = new ProxyFactory(bean);
+ // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
+ proxyFactory.copyFrom(this);
+ proxyFactory.addAdvisor(this.advisor);
+ return proxyFactory.getProxy(this.beanClassLoader);
+ }
+ }
+ else {
+ // No async proxy needed.
+ return bean;
+ }
+ }
+
+ /**
+ * Check whether the given bean is eligible for advising with this
+ * post-processor's {@link Advisor}.
+ * <p>Implements caching of <code>canApply</code> results per bean name.
+ * @param bean the bean instance
+ * @param beanName the name of the bean
+ * @see AopUtils#canApply(Advisor, Class)
+ */
+ protected boolean isEligible(Object bean, String beanName) {
+ Boolean eligible = this.eligibleBeans.get(beanName);
+ if (eligible != null) {
+ return eligible;
+ }
+ Class<?> targetClass = AopUtils.getTargetClass(bean);
+ eligible = AopUtils.canApply(this.advisor, targetClass);
+ this.eligibleBeans.put(beanName, eligible);
+ return eligible;
+ }
+
+}
@@ -19,21 +19,11 @@
import java.lang.annotation.Annotation;
import java.util.concurrent.Executor;
-import org.springframework.aop.framework.Advised;
-import org.springframework.aop.framework.AopInfrastructureBean;
-import org.springframework.aop.framework.ProxyConfig;
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.core.Ordered;
import org.springframework.core.task.TaskExecutor;
import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
/**
* Bean post-processor that automatically applies asynchronous invocation
@@ -55,26 +45,13 @@
* @see AsyncAnnotationAdvisor
*/
@SuppressWarnings("serial")
-public class AsyncAnnotationBeanPostProcessor extends ProxyConfig
- implements BeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware,
- InitializingBean, Ordered {
+public class AsyncAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostProcessor
+ implements BeanFactoryAware {
private Class<? extends Annotation> asyncAnnotationType;
private Executor executor;
- private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
-
- private AsyncAnnotationAdvisor asyncAnnotationAdvisor;
-
- /**
- * This should run after all other post-processors, so that it can just add
- * an advisor to existing proxies rather than double-proxy.
- */
- private int order = Ordered.LOWEST_PRECEDENCE;
-
- private BeanFactory beanFactory;
-
/**
* Set the 'async' annotation type to be detected at either class or method
@@ -97,59 +74,14 @@ public void setExecutor(Executor executor) {
this.executor = executor;
}
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- this.beanFactory = beanFactory;
- }
-
- public void afterPropertiesSet() {
- this.asyncAnnotationAdvisor = (this.executor != null ?
+ public void setBeanFactory(BeanFactory beanFactory) {
+ AsyncAnnotationAdvisor advisor = (this.executor != null ?
new AsyncAnnotationAdvisor(this.executor) : new AsyncAnnotationAdvisor());
if (this.asyncAnnotationType != null) {
- this.asyncAnnotationAdvisor.setAsyncAnnotationType(this.asyncAnnotationType);
- }
- this.asyncAnnotationAdvisor.setBeanFactory(this.beanFactory);
- }
-
- public int getOrder() {
- return this.order;
- }
-
- public void setOrder(int order) {
- this.order = order;
- }
-
-
- public Object postProcessBeforeInitialization(Object bean, String beanName) {
- return bean;
- }
-
- public Object postProcessAfterInitialization(Object bean, String beanName) {
- if (bean instanceof AopInfrastructureBean) {
- // Ignore AOP infrastructure such as scoped proxies.
- return bean;
- }
- Class<?> targetClass = AopUtils.getTargetClass(bean);
- if (AopUtils.canApply(this.asyncAnnotationAdvisor, targetClass)) {
- if (bean instanceof Advised) {
- ((Advised) bean).addAdvisor(0, 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;
+ advisor.setAsyncAnnotationType(this.asyncAnnotationType);
}
+ advisor.setBeanFactory(beanFactory);
+ this.advisor = advisor;
}
}
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 the original author or authors.
+ * Copyright 2002-2012 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.
@@ -24,6 +24,7 @@
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
+import org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AopInfrastructureBean;
import org.springframework.aop.framework.ProxyConfig;
@@ -67,17 +68,12 @@
* @see org.hibernate.validator.method.MethodValidator
*/
@SuppressWarnings("serial")
-public class MethodValidationPostProcessor extends ProxyConfig
- implements BeanPostProcessor, BeanClassLoaderAware, Ordered, InitializingBean {
+public class MethodValidationPostProcessor extends AbstractAdvisingBeanPostProcessor {
private Class<? extends Annotation> validatedAnnotationType = Validated.class;
private Validator validator;
- private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
-
- private Advisor advisor;
-
/**
* Set the 'validated' annotation type.
@@ -110,52 +106,11 @@ public void setValidatorFactory(ValidatorFactory validatorFactory) {
this.validator = validatorFactory.getValidator();
}
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- public int getOrder() {
- // This should run after all other post-processors, so that it can just add
- // an advisor to existing proxies rather than double-proxy.
- return LOWEST_PRECEDENCE;
- }
-
-
public void afterPropertiesSet() {
Pointcut pointcut = new AnnotationMatchingPointcut(this.validatedAnnotationType, true);
Advice advice = (this.validator != null ? new MethodValidationInterceptor(this.validator) :
new MethodValidationInterceptor());
this.advisor = new DefaultPointcutAdvisor(pointcut, advice);
}
-
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
-
- 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 (AopUtils.canApply(this.advisor, targetClass)) {
- if (bean instanceof Advised) {
- ((Advised) bean).addAdvisor(this.advisor);
- return bean;
- }
- else {
- ProxyFactory proxyFactory = new ProxyFactory(bean);
- // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
- proxyFactory.copyFrom(this);
- proxyFactory.addAdvisor(this.advisor);
- return proxyFactory.getProxy(this.beanClassLoader);
- }
- }
- else {
- // This is not a repository.
- return bean;
- }
- }
-
}
Oops, something went wrong.

0 comments on commit 0a3ea42

Please sign in to comment.