Browse Source

Cache InjectionMetadata per bean name instead of per Class

Issue: SPR-11027
pull/393/merge
Juergen Hoeller 11 years ago committed by unknown
parent
commit
393cfcff40
  1. 18
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
  2. 16
      spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java
  3. 16
      spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java
  4. 18
      spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceInjectionTests.java

18
spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

@ -121,8 +121,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean @@ -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 @@ -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 @@ -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 @@ -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 @@ -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);
}
}
}

16
spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java

@ -174,8 +174,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean @@ -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 @@ -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 @@ -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 @@ -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 @@ -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);
}
}
}

16
spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java

@ -187,8 +187,8 @@ public class PersistenceAnnotationBeanPostProcessor @@ -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 @@ -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 @@ -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 @@ -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 @@ -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);
}
}
}

18
spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceInjectionTests.java

@ -23,7 +23,6 @@ import java.lang.reflect.Proxy; @@ -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; @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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…
Cancel
Save