DefaultSingletonBeanRegistry avoids singletonObjects lock wherever possible for non-singleton factory performance
Issue: SPR-9819
This commit is contained in:
parent
c24825ca19
commit
0a3ea42fe1
|
|
@ -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 @@ package org.springframework.scheduling.annotation;
|
|||
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 @@ import org.springframework.util.ClassUtils;
|
|||
* @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 class AsyncAnnotationBeanPostProcessor extends ProxyConfig
|
|||
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.aopalliance.aop.Advice;
|
|||
|
||||
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 @@ import org.springframework.validation.annotation.Validated;
|
|||
* @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,17 +106,6 @@ public class MethodValidationPostProcessor extends ProxyConfig
|
|||
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) :
|
||||
|
|
@ -128,34 +113,4 @@ public class MethodValidationPostProcessor extends ProxyConfig
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -18,21 +18,12 @@ package org.springframework.dao.annotation;
|
|||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
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.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Bean post-processor that automatically applies persistence exception translation to any
|
||||
|
|
@ -67,15 +58,11 @@ import org.springframework.util.ClassUtils;
|
|||
* @see org.springframework.dao.support.PersistenceExceptionTranslator
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class PersistenceExceptionTranslationPostProcessor extends ProxyConfig
|
||||
implements BeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware, Ordered {
|
||||
public class PersistenceExceptionTranslationPostProcessor extends AbstractAdvisingBeanPostProcessor
|
||||
implements BeanFactoryAware {
|
||||
|
||||
private Class<? extends Annotation> repositoryAnnotationType = Repository.class;
|
||||
|
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private PersistenceExceptionTranslationAdvisor persistenceExceptionTranslationAdvisor;
|
||||
|
||||
|
||||
/**
|
||||
* Set the 'repository' annotation type.
|
||||
|
|
@ -90,53 +77,13 @@ public class PersistenceExceptionTranslationPostProcessor extends ProxyConfig
|
|||
this.repositoryAnnotationType = repositoryAnnotationType;
|
||||
}
|
||||
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (!(beanFactory instanceof ListableBeanFactory)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot use PersistenceExceptionTranslator autodetection without ListableBeanFactory");
|
||||
}
|
||||
this.persistenceExceptionTranslationAdvisor = new PersistenceExceptionTranslationAdvisor(
|
||||
this.advisor = new PersistenceExceptionTranslationAdvisor(
|
||||
(ListableBeanFactory) beanFactory, this.repositoryAnnotationType);
|
||||
}
|
||||
|
||||
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 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.persistenceExceptionTranslationAdvisor, targetClass)) {
|
||||
if (bean instanceof Advised) {
|
||||
((Advised) bean).addAdvisor(this.persistenceExceptionTranslationAdvisor);
|
||||
return bean;
|
||||
}
|
||||
else {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(bean);
|
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this);
|
||||
proxyFactory.addAdvisor(this.persistenceExceptionTranslationAdvisor);
|
||||
return proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is not a repository.
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue