From 8db9926d414bb6306ec363d3ab2e1b1ce4c89485 Mon Sep 17 00:00:00 2001 From: trytocatch Date: Sun, 28 Aug 2022 17:57:48 +0800 Subject: [PATCH] Make it compatible when the property value changes --- ...hingDelegateEncryptablePropertySource.java | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/caching/CachingDelegateEncryptablePropertySource.java b/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/caching/CachingDelegateEncryptablePropertySource.java index ed98617..666d999 100644 --- a/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/caching/CachingDelegateEncryptablePropertySource.java +++ b/jasypt-spring-boot/src/main/java/com/ulisesbocchio/jasyptspringboot/caching/CachingDelegateEncryptablePropertySource.java @@ -3,9 +3,12 @@ import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter; import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver; import com.ulisesbocchio.jasyptspringboot.EncryptablePropertySource; -import java.util.HashMap; + import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.env.PropertySource; import org.springframework.util.Assert; @@ -15,7 +18,7 @@ public class CachingDelegateEncryptablePropertySource extends PropertySource< private final PropertySource delegate; private final EncryptablePropertyResolver resolver; private final EncryptablePropertyFilter filter; - private final Map cache; + private final Map cache; public CachingDelegateEncryptablePropertySource(PropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) { super(delegate.getName(), delegate.getSource()); @@ -25,7 +28,7 @@ public CachingDelegateEncryptablePropertySource(PropertySource delegate, Encr this.delegate = delegate; this.resolver = resolver; this.filter = filter; - this.cache = new HashMap<>(); + this.cache = new ConcurrentHashMap<>(); } @Override @@ -35,19 +38,37 @@ public PropertySource getDelegate() { @Override public Object getProperty(String name) { - // Can be called recursively, so, we cannot use computeIfAbsent. - if (cache.containsKey(name)) { - return cache.get(name); + //The purpose of this cache is to reduce the cost of decryption, + // so it's not a bad idea to read the original property every time, it's generally fast. + Object originValue = delegate.getProperty(name); + if (!(originValue instanceof String)) { + //Because we read the original property every time, if it isn't a String, + // there's no point in caching it. + return originValue; + } + + CachedValue cachedValue = cache.get(name); + if (cachedValue != null && Objects.equals(originValue, cachedValue.originValue)) { + // If the original property has not changed, it is safe to return the cached result. + return cachedValue.resolvedValue; } - synchronized (name.intern()) { - if (!cache.containsKey(name)) { - Object resolved = getProperty(resolver, filter, delegate, name); - if (resolved != null) { - cache.put(name, resolved); - } + + //originValue must be String here + if (filter.shouldInclude(delegate, name)) { + String originStringValue = (String) originValue; + String resolved = resolver.resolvePropertyValue(originStringValue); + CachedValue newCachedValue = new CachedValue(originStringValue, resolved); + //If the mapping relationship in the cache changes during + // the calculation process, then ignore it directly. + if (cachedValue == null) { + cache.putIfAbsent(name, newCachedValue); + } else { + cache.replace(name, cachedValue, newCachedValue); } - return cache.get(name); + //return the result calculated this time + return resolved; } + return originValue; } @Override @@ -55,4 +76,10 @@ public void refresh() { log.info("Property Source {} refreshed", delegate.getName()); cache.clear(); } + + @AllArgsConstructor + private static class CachedValue { + private final String originValue; + private final String resolvedValue; + } }