From b1460742c37f0de3c606d3710798c9ff8af2fb80 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 19 Dec 2013 23:49:31 +0100 Subject: [PATCH] InjectionMetadata caching per bean name needs to refresh when bean class changes Issue: SPR-11246 --- .../annotation/AutowiredAnnotationBeanPostProcessor.java | 4 ++-- .../beans/factory/annotation/InjectionMetadata.java | 5 +++++ .../annotation/CommonAnnotationBeanPostProcessor.java | 4 ++-- .../jpa/support/PersistenceAnnotationBeanPostProcessor.java | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 8db6d6fff0..d366a36e8f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -317,10 +317,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); - if (metadata == null) { + if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); - if (metadata == null) { + if (InjectionMetadata.needsRefresh(metadata, clazz)) { metadata = buildAutowiringMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java index 26a0d0b7f7..636b103764 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java @@ -90,6 +90,11 @@ public class InjectionMetadata { } + public static boolean needsRefresh(InjectionMetadata metadata, Class clazz) { + return (metadata == null || !metadata.targetClass.equals(clazz)); + } + + public static abstract class InjectedElement { protected final Member member; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index 239ac169ad..c973a01b08 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -315,10 +315,10 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); - if (metadata == null) { + if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); - if (metadata == null) { + if (InjectionMetadata.needsRefresh(metadata, clazz)) { LinkedList elements = new LinkedList(); Class targetClass = clazz; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index ef3e4af4d5..51ee76472a 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -380,10 +380,10 @@ public class PersistenceAnnotationBeanPostProcessor // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); - if (metadata == null) { + if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); - if (metadata == null) { + if (InjectionMetadata.needsRefresh(metadata, clazz)) { LinkedList elements = new LinkedList(); Class targetClass = clazz;