Class AbstractConcurrentCustomScope<A extends Annotation>
- Type Parameters:
A- The annotation type
- All Implemented Interfaces:
LifeCycle<AbstractConcurrentCustomScope<A>>, CustomScope<A>, Closeable, AutoCloseable
By default this implementation uses a single ReentrantReadWriteLock to lock the entire scope, and holds
its write lock while a bean is created, hence it is designed for scopes that will hold a small amount of beans whose
creation never waits on another thread. A scope that holds many beans, or whose beans may wait during creation for
another thread that creates a bean of the same scope, should opt into a lock per BeanIdentifier through
AbstractConcurrentCustomScope(Class, boolean).
- Since:
- 3.0.0
- Author:
- graemerocher
-
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedAbstractConcurrentCustomScope(Class<A> annotationType) A custom scope annotation.protectedAbstractConcurrentCustomScope(Class<A> annotationType, boolean lockPerBean) A custom scope annotation, choosing how creation is locked. -
Method Summary
Modifier and TypeMethodDescriptionabstract voidclose()Implement the close logic for the scope.protected voiddestroyScope(@Nullable Map<BeanIdentifier, CreatedBean<?>> scopeMap) Destroys the scope.protected <T> CreatedBean<T> doCreate(BeanCreationContext<T> creationContext) Perform creation.<T> Optional<BeanRegistration<T>> findBeanRegistration(BeanDefinition<T> beanDefinition) Finds the registration held for the given definition.final <T> Optional<BeanRegistration<T>> findBeanRegistration(T bean) Get theBeanDefinitionfor the given bean.final <T> TgetOrCreate(BeanCreationContext<T> creationContext) Resolve an object from the given scope.protected abstract @Nullable Map<BeanIdentifier, CreatedBean<?>> getScopeMap(boolean forCreation) protected voidMethod that can be overridden to customize what happens on a shutdown error.<T> Optional<T> remove(BeanDefinition<T> beanDefinition) Remove and destroy the bean held for the given definition.final <T> Optional<T> remove(BeanIdentifier identifier) Remove a bean definition from the scope.final AbstractConcurrentCustomScope<A> stop()Stops the life cycle component.
-
Constructor Details
-
AbstractConcurrentCustomScope
-
AbstractConcurrentCustomScope
A custom scope annotation, choosing how creation is locked.With
lockPerBeanthe scope-wide lock is not used at all. A bean is created under a lock that belongs to itsBeanIdentifieralone, so that beans of different identifiers are created in parallel, a creation may wait for another thread that creates a bean of the same scope, and the fast path of a bean already held is a plain lookup.remove(BeanIdentifier)takes the same lock, so it still waits for a creation of that identifier in flight and then destroys what was created, and so doremove(BeanDefinition)anddestroyScope(Map), which wait for the creations in flight of the map they work on. Nothing else holds creation off: a creation that has not begun when a destruction of the scope map ends publishes its bean into that map afterwards, exactly as one that arrives after the scope-wide write lock is released does.findBeanRegistration(Object)works on the scope map without any lock, which is why the map returned bygetScopeMap(boolean)must then be aConcurrentMap:getOrCreate(BeanCreationContext)rejects any other map with anIllegalStateException. The lock objects live as long as the scope, one per identifier ever created or removed through it.- Parameters:
annotationType- The annotation typelockPerBean- Whether to lock creation perBeanIdentifierrather than for the whole scope- Since:
- 5.2.0
-
-
Method Details
-
getScopeMap
- Parameters:
forCreation- Whether it is for creation- Returns:
- Obtains the scope map, never null
- Throws:
IllegalStateException- if the scope map cannot be obtained in the current context
-
annotationType
- Specified by:
annotationTypein interfaceCustomScope<A extends Annotation>- Returns:
- The scope annotation type
-
close
public abstract void close()Implement the close logic for the scope.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Specified by:
closein interfaceLifeCycle<A extends Annotation>
-
stop
Description copied from interface:LifeCycleStops the life cycle component.- Specified by:
stopin interfaceLifeCycle<A extends Annotation>- Returns:
- This lifecycle component
-
destroyScope
Destroys the scope.- Parameters:
scopeMap- The scope map
-
getOrCreate
Description copied from interface:CustomScopeResolve an object from the given scope.- Specified by:
getOrCreatein interfaceCustomScope<A extends Annotation>- Type Parameters:
T- The bean generic type- Parameters:
creationContext- The creation context- Returns:
- The bean instance
-
doCreate
Perform creation.- Type Parameters:
T- The generic type- Parameters:
creationContext- The creation context- Returns:
- Created bean
-
remove
Description copied from interface:CustomScopeRemove a bean definition from the scope.- Specified by:
removein interfaceCustomScope<A extends Annotation>- Type Parameters:
T- The generic type- Parameters:
identifier- TheBeanIdentifier- Returns:
- An
Optionalof the instance that was destroyed if it exists
-
remove
Remove and destroy the bean held for the given definition. The definition may be theProxyBeanDefinitionof a scoped proxy, in which case the target it stands for is removed.The bean is taken out of the scope under the write lock, or, where creation is locked per bean, under the lock of the identifier it is held under, having first waited for the creations into the scope map that are in flight so that a bean of the definition one of them is about to publish is not missed. It is closed after the lock is released, so a
@PreDestroyhook may reach into the scope from another thread without deadlocking on it. Unlikeremove(BeanIdentifier)a destruction failure is not routed throughhandleDestructionException(BeanDestructionException)but propagated to the caller.- Type Parameters:
T- The generic type- Parameters:
beanDefinition- The bean definition- Returns:
- An
Optionalof the instance that was destroyed if it exists - Throws:
BeanDestructionException- If destroying the bean fails- Since:
- 5.2.0
-
handleDestructionException
Method that can be overridden to customize what happens on a shutdown error.- Parameters:
e- The exception
-
findBeanRegistration
Description copied from interface:CustomScopeGet theBeanDefinitionfor the given bean.- Specified by:
findBeanRegistrationin interfaceCustomScope<A extends Annotation>- Type Parameters:
T- The bean generic type- Parameters:
bean- The bean- Returns:
- The bean definition if it can be resolved
-
findBeanRegistration
Finds the registration held for the given definition. The definition may be theProxyBeanDefinitionof a scoped proxy, in which case the registration of the target it stands for is returned.- Specified by:
findBeanRegistrationin interfaceCustomScope<A extends Annotation>- Type Parameters:
T- The bean generic type- Parameters:
beanDefinition- The bean definition- Returns:
- The registration if the scope holds an instance for the definition
- Since:
- 5.2.0
-