Cache InjectionMetadata per bean name instead of per Class
Issue: SPR-11027
This commit is contained in:
parent
166b7a906e
commit
393cfcff40
|
@ -121,8 +121,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache =
|
||||
new ConcurrentHashMap<Class<?>, Constructor<?>[]>(64);
|
||||
|
||||
private final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
|
||||
private final Map<String, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<String, InjectionMetadata>(64);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -217,7 +217,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
if (beanType != null) {
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanType);
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType);
|
||||
metadata.checkConfigMembers(beanDefinition);
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
|
||||
try {
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
*/
|
||||
public void processInjection(Object bean) throws BeansException {
|
||||
Class<?> clazz = bean.getClass();
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz);
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz);
|
||||
try {
|
||||
metadata.inject(bean, null, null);
|
||||
}
|
||||
|
@ -311,15 +311,15 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
}
|
||||
|
||||
|
||||
private InjectionMetadata findAutowiringMetadata(Class<?> clazz) {
|
||||
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz) {
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(beanName);
|
||||
if (metadata == null) {
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(clazz);
|
||||
metadata = this.injectionMetadataCache.get(beanName);
|
||||
if (metadata == null) {
|
||||
metadata = buildAutowiringMetadata(clazz);
|
||||
this.injectionMetadataCache.put(clazz, metadata);
|
||||
this.injectionMetadataCache.put(beanName, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,8 +174,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
|
||||
private transient BeanFactory beanFactory;
|
||||
|
||||
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
|
||||
private transient final Map<String, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<String, InjectionMetadata>(64);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -280,7 +280,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
|
||||
if (beanType != null) {
|
||||
InjectionMetadata metadata = findResourceMetadata(beanType);
|
||||
InjectionMetadata metadata = findResourceMetadata(beanName, beanType);
|
||||
metadata.checkConfigMembers(beanDefinition);
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findResourceMetadata(bean.getClass());
|
||||
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass());
|
||||
try {
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
|
@ -310,12 +310,12 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
}
|
||||
|
||||
|
||||
private InjectionMetadata findResourceMetadata(final Class<?> clazz) {
|
||||
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz) {
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(beanName);
|
||||
if (metadata == null) {
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(clazz);
|
||||
metadata = this.injectionMetadataCache.get(beanName);
|
||||
if (metadata == null) {
|
||||
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
Class<?> targetClass = clazz;
|
||||
|
@ -389,7 +389,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
while (targetClass != null && targetClass != Object.class);
|
||||
|
||||
metadata = new InjectionMetadata(clazz, elements);
|
||||
this.injectionMetadataCache.put(clazz, metadata);
|
||||
this.injectionMetadataCache.put(beanName, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,8 +187,8 @@ public class PersistenceAnnotationBeanPostProcessor
|
|||
|
||||
private transient ListableBeanFactory beanFactory;
|
||||
|
||||
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
|
||||
private transient final Map<String, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<String, InjectionMetadata>(64);
|
||||
|
||||
private final Map<Object, EntityManager> extendedEntityManagersToClose =
|
||||
new ConcurrentHashMap<Object, EntityManager>(16);
|
||||
|
@ -328,7 +328,7 @@ public class PersistenceAnnotationBeanPostProcessor
|
|||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
if (beanType != null) {
|
||||
InjectionMetadata metadata = findPersistenceMetadata(beanType);
|
||||
InjectionMetadata metadata = findPersistenceMetadata(beanName, beanType);
|
||||
metadata.checkConfigMembers(beanDefinition);
|
||||
}
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ public class PersistenceAnnotationBeanPostProcessor
|
|||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findPersistenceMetadata(bean.getClass());
|
||||
InjectionMetadata metadata = findPersistenceMetadata(beanName, bean.getClass());
|
||||
try {
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
|
@ -374,12 +374,12 @@ public class PersistenceAnnotationBeanPostProcessor
|
|||
}
|
||||
|
||||
|
||||
private InjectionMetadata findPersistenceMetadata(final Class<?> clazz) {
|
||||
private InjectionMetadata findPersistenceMetadata(String beanName, final Class<?> clazz) {
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(beanName);
|
||||
if (metadata == null) {
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(clazz);
|
||||
metadata = this.injectionMetadataCache.get(beanName);
|
||||
if (metadata == null) {
|
||||
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
Class<?> targetClass = clazz;
|
||||
|
@ -417,7 +417,7 @@ public class PersistenceAnnotationBeanPostProcessor
|
|||
while (targetClass != null && targetClass != Object.class);
|
||||
|
||||
metadata = new InjectionMetadata(clazz, elements);
|
||||
this.injectionMetadataCache.put(clazz, metadata);
|
||||
this.injectionMetadataCache.put(beanName, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.lang.reflect.Proxy;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
@ -34,6 +33,7 @@ import javax.persistence.PersistenceUnit;
|
|||
import org.hibernate.ejb.HibernateEntityManager;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
|
@ -524,7 +524,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
|||
public void testFieldOfWrongTypeAnnotatedWithPersistenceUnit() {
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
try {
|
||||
babpp.postProcessPropertyValues(null, null, new FieldOfWrongTypeAnnotatedWithPersistenceUnit(), null);
|
||||
babpp.postProcessPropertyValues(null, null, new FieldOfWrongTypeAnnotatedWithPersistenceUnit(), "bean");
|
||||
fail("Can't inject this field");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
|
@ -536,7 +536,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
|||
public void testSetterOfWrongTypeAnnotatedWithPersistenceUnit() {
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
try {
|
||||
babpp.postProcessPropertyValues(null, null, new SetterOfWrongTypeAnnotatedWithPersistenceUnit(), null);
|
||||
babpp.postProcessPropertyValues(null, null, new SetterOfWrongTypeAnnotatedWithPersistenceUnit(), "bean");
|
||||
fail("Can't inject this setter");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
|
@ -548,7 +548,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
|||
public void testSetterWithNoArgs() {
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
try {
|
||||
babpp.postProcessPropertyValues(null, null, new SetterWithNoArgs(), null);
|
||||
babpp.postProcessPropertyValues(null, null, new SetterWithNoArgs(), "bean");
|
||||
fail("Can't inject this setter");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
|
@ -593,7 +593,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
|||
PersistenceAnnotationBeanPostProcessor babpp = new MockPersistenceAnnotationBeanPostProcessor();
|
||||
DefaultPrivatePersistenceContextFieldWithProperties transactionalField =
|
||||
new DefaultPrivatePersistenceContextFieldWithProperties();
|
||||
babpp.postProcessPropertyValues(null, null, transactionalField, null);
|
||||
babpp.postProcessPropertyValues(null, null, transactionalField, "bean");
|
||||
|
||||
assertNotNull(transactionalField.em);
|
||||
assertNotNull(transactionalField.em.getDelegate());
|
||||
|
@ -620,8 +620,8 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
|||
new DefaultPrivatePersistenceContextFieldWithProperties();
|
||||
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
|
||||
|
||||
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, null);
|
||||
babpp.postProcessPropertyValues(null, null, transactionalField, null);
|
||||
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, "bean1");
|
||||
babpp.postProcessPropertyValues(null, null, transactionalField, "bean2");
|
||||
|
||||
assertNotNull(transactionalFieldWithProperties.em);
|
||||
assertNotNull(transactionalField.em);
|
||||
|
@ -653,8 +653,8 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
|||
new DefaultPrivatePersistenceContextFieldWithProperties();
|
||||
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
|
||||
|
||||
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, null);
|
||||
babpp.postProcessPropertyValues(null, null, transactionalField, null);
|
||||
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, "bean1");
|
||||
babpp.postProcessPropertyValues(null, null, transactionalField, "bean2");
|
||||
|
||||
assertNotNull(transactionalFieldWithProperties.em);
|
||||
assertNotNull(transactionalField.em);
|
||||
|
|
Loading…
Reference in New Issue