
com.github.nill14.utils.init.scope.ScopeContext Maven / Gradle / Ivy
The newest version!
package com.github.nill14.utils.init.scope;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Provider;
import com.github.nill14.utils.init.api.BindingKey;
import com.github.nill14.utils.init.api.IBeanDescriptor;
import com.github.nill14.utils.init.api.IPropertyResolver;
import com.github.nill14.utils.init.api.IScopeContext;
import com.github.nill14.utils.init.impl.UnscopedProvider;
import com.google.common.collect.Lists;
public final class ScopeContext implements IScopeContext {
private final AtomicBoolean lifecycleTracker = new AtomicBoolean(true);
private final ConcurrentHashMap, ScopedProvider>> map = new ConcurrentHashMap<>();
public ScopeContext() {
}
@SuppressWarnings("unchecked")
public Provider scope(BindingKey type, Provider unscoped) {
if (!(unscoped instanceof UnscopedProvider)) {
throw new IllegalArgumentException();
}
if (lifecycleTracker.get()) {
return (Provider) map.computeIfAbsent(type, (t) -> new ScopedProvider<>(
(UnscopedProvider) unscoped));
} else {
throw new RuntimeException("Cannot retrieve a bean from terminated scope");
}
}
private class ScopedProvider implements Provider {
private final UnscopedProvider unscoped;
private volatile T instance;
public ScopedProvider(UnscopedProvider unscoped) {
this.unscoped = unscoped;
}
@Override
public T get() {
T instance = this.instance;
if (instance == null) {
synchronized (this) {
instance = this.instance;
if (instance == null) {
instance = unscoped.get();
this.instance = instance;
}
}
}
return instance;
}
private void destroy() {
T instance;
synchronized (this) {
instance = this.instance;
this.instance = null;
}
if (instance != null) {
IBeanDescriptor beanDescriptor = unscoped.getDescriptor();
IPropertyResolver resolver = unscoped.getResolver();
resolver.destroyBean(beanDescriptor, instance);
}
}
}
public void terminate() {
if (lifecycleTracker.compareAndSet(true, false)) {
List> providers = Lists.newArrayList(map.values());
map.clear();
for (ScopedProvider> provider : providers) {
provider.destroy();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy