private <T> T newInstance(final Bean<T> bean, final ReleaseCallbackHandler handler) { final CreationalContextImpl<T> ctx = contextFor(bean, handler); final T instance = bean.create(ctx); ctx.addDependentInstance(new ContextualInstance<T>() { @Override public T getInstance() { return instance; } @Override public CreationalContext<T> getCreationalContext() { return ctx; } @Override public Contextual<T> getContextual() { return bean; } }); return instance; }
/** * Retrieves the map that contains transaction scoped beans for the current * transaction. * * @param transactionSupport a bean that implements {@link TransactionSupport}. * @return instances of transaction scoped beans for the current * transaction. */ private <T> Map<Contextual<T>, ContextualInstance<T>> getInstances( TransactionSupport transactionSupport) { @SuppressWarnings("unchecked") Map<Contextual<T>, ContextualInstance<T>> instances = (Map<Contextual<T>, ContextualInstance<T>>) transactionSupport.getTransactionSynchronizationRegistry() .getResource(TRANSACTION_BEANS_KEY); if (instances == null) { instances = new HashMap<Contextual<T>, ContextualInstance<T>>(); transactionSupport .getTransactionSynchronizationRegistry() .putResource(TRANSACTION_BEANS_KEY, instances); registerSynchronization(transactionSupport, instances); } return instances; }
@SuppressWarnings("unchecked") public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext) { Map<Contextual<?>, ContextualInstance<?>> ctx = currentContext.get(); if (ctx == null) { // Thread local not set - context is not active! throw new ContextNotActiveException(); } ContextualInstance<T> instance = (ContextualInstance<T>) ctx.get(contextual); if (instance == null && creationalContext != null) { // Bean instance does not exist - create one if we have CreationalContext instance = new ContextualInstance<T>(contextual.create(creationalContext), creationalContext, contextual); ctx.put(contextual, instance); } return instance != null ? instance.get() : null; }
/** * * @param contextual * @return */ private Session getSession(Contextual<?> contextual) { final List<Session> sessions = new ArrayList<>(); final SessionRegistry registry = getContextualReference(this.beanManager, SessionRegistry.class, false); for (Entry<String, ContextualStorage> e : this.holder.getStorageMap().entrySet()) { final Object key = e.getValue().getBeanKey(contextual); if (e.getValue().getBean(key) != null) { final Optional<Session> session = registry.getSession(e.getKey()); session.ifPresent(sessions::add); } } if (sessions.size() > 1) { throw new IllegalStateException("Too many sessions! [" + contextual + "]"); } return sessions.isEmpty() ? null : sessions.get(0); }
public void deactivate() { Map<Contextual<?>, ContextualInstance<?>> ctx = currentContext.get(); if (ctx == null) { return; } for (ContextualInstance<?> instance : ctx.values()) { try { instance.destroy(); } catch (Exception e) { LOGGER.warning("Unable to destroy instance" + instance.get() + " for bean: " + instance.getContextual()); } } ctx.clear(); currentContext.remove(); currentCommandExecution.remove(); }
/** * Destroy the instance. * * @param contextual the contextual. */ public void destroy(Contextual contextual) { String scopeId = (String) request.getAttribute(SCOPE_ID); if (null != scopeId) { HttpSession session = request.getSession(); if (contextual instanceof PassivationCapable == false) { throw new RuntimeException("Unexpected type for contextual"); } PassivationCapable pc = (PassivationCapable) contextual; final String sessionKey = SCOPE_ID + "-" + scopeId; Map<String, Object> scopeMap = (Map<String, Object>) session.getAttribute(sessionKey); if (null != scopeMap) { Object instance = scopeMap.get(INSTANCE + pc.getId()); CreationalContext<?> creational = (CreationalContext<?>) scopeMap.get(CREATIONAL + pc.getId()); if (null != instance && null != creational) { contextual.destroy(instance, creational); creational.release(); } } } }
/** * Get the instance. * * @param <T> the type. * @param contextual the contextual. * @return the instance, or null. */ public <T> T get(Contextual<T> contextual) { T result = null; String scopeId = (String) request.getAttribute(SCOPE_ID); if (null != scopeId) { HttpSession session = request.getSession(); if (contextual instanceof PassivationCapable == false) { throw new RuntimeException("Unexpected type for contextual"); } PassivationCapable pc = (PassivationCapable) contextual; final String sessionKey = SCOPE_ID + "-" + scopeId; Map<String, Object> scopeMap = (Map<String, Object>) session.getAttribute(sessionKey); if (null != scopeMap) { result = (T) scopeMap.get(INSTANCE + pc.getId()); } else { request.setAttribute(SCOPE_ID, null); // old cookie, force new scope generation } } return result; }
/** * Get the instance (create it if it does not exist). * * @param <T> the type. * @param contextual the contextual. * @param creational the creational. * @return the instance. */ public <T> T get(Contextual<T> contextual, CreationalContext<T> creational) { T result = get(contextual); if (result == null) { String scopeId = (String) request.getAttribute(SCOPE_ID); if (null == scopeId) { scopeId = generateScopeId(); } HttpSession session = request.getSession(); result = contextual.create(creational); if (contextual instanceof PassivationCapable == false) { throw new RuntimeException("Unexpected type for contextual"); } PassivationCapable pc = (PassivationCapable) contextual; final String sessionKey = SCOPE_ID + "-" + scopeId; Map<String, Object> scopeMap = (Map<String, Object>) session.getAttribute(sessionKey); if (null != scopeMap) { session.setAttribute(sessionKey, scopeMap); scopeMap.put(INSTANCE + pc.getId(), result); scopeMap.put(CREATIONAL + pc.getId(), creational); } } return result; }
public void deactivate() { Map<Contextual<?>, ContextualInstance<?>> ctx = currentContext.get(); if (ctx == null) { return; } for (ContextualInstance<?> instance : ctx.values()) { try { instance.destroy(); } catch (Exception e) { e.printStackTrace(); } } ctx.clear(); currentContext.remove(); currentArchive.set(null); currentName.set(null); }
@Override public <T> T get(Contextual<T> contextual) { Bean<T> bean = (Bean<T>) contextual; String variableName = bean.getName(); BusinessProcess businessProcess = getBusinessProcess(); Object variable = businessProcess.getVariable(variableName); if (variable != null) { if (LOGGER.isDebugEnabled()) { if (businessProcess.isAssociated()) { LOGGER.debug("Getting instance of bean '{}' from Execution[{}]", variableName, businessProcess.getExecutionId()); } else { LOGGER.debug("Getting instance of bean '{}' from transient bean store", variableName); } } return (T) variable; } else { return null; } }
@SuppressWarnings("unchecked") @Override public <T> T get(final Contextual<T> component, final CreationalContext<T> creationalContext) { assertActive(); T instance = get(component); if (instance == null) { if (creationalContext != null) { Map<Contextual<?>, Object> componentInstanceMap = getComponentInstanceMap(); Map<Contextual<?>, CreationalContext<?>> creationalContextMap = getCreationalInstanceMap(); synchronized (componentInstanceMap) { instance = (T) componentInstanceMap.get(component); if (instance == null) { instance = component.create(creationalContext); if (instance != null) { componentInstanceMap.put(component, instance); creationalContextMap.put(component, creationalContext); } } } } } return instance; }
/** * We get PreDestroyViewMapEvent events from the JSF servlet and destroy our * contextual instances. This should (theoretically!) also get fired if the * webapp closes, so there should be no need to manually track all view * scopes and destroy them at a shutdown. * * @see javax.faces.event.SystemEventListener#processEvent(javax.faces.event.SystemEvent) */ @SuppressWarnings("unchecked") @Override public void processEvent(final SystemEvent event) { if (event instanceof PreDestroyViewMapEvent) { Map<Contextual<?>, Object> componentInstanceMap = getComponentInstanceMap(); Map<Contextual<?>, CreationalContext<?>> creationalContextMap = getCreationalInstanceMap(); if (componentInstanceMap != null) { for (Map.Entry<Contextual<?>, Object> componentEntry : componentInstanceMap.entrySet()) { /* * No way to inform the compiler of type <T> information, so * it has to be abandoned here :( */ Contextual contextual = componentEntry.getKey(); Object instance = componentEntry.getValue(); CreationalContext creational = creationalContextMap.get(contextual); contextual.destroy(instance, creational); } } } }
@Override public <T> T get(Contextual<T> contextual) { Bean<T> bean = (Bean<T>) contextual; String variableName = bean.getName(); BusinessProcess businessProcess = getBusinessProcess(); Object variable = businessProcess.getVariable(variableName); if (variable != null) { if (logger.isLoggable(Level.FINE)) { if(businessProcess.isAssociated()) { logger.fine("Getting instance of bean '" + variableName + "' from Execution[" + businessProcess.getExecutionId() + "]."); } else { logger.fine("Getting instance of bean '" + variableName + "' from transient bean store"); } } return (T) variable; } else { return null; } }
@Override protected ContextualStorage getContextualStorage(Contextual<?> contextual, boolean createIfNotExist) { Object val = getDolphinSession().getAttribute(CLIENT_STORAGE_ATTRIBUTE); if(val != null) { if(val instanceof ContextualStorage) { return (ContextualStorage) val; } else { throw new ContextException("No ClientContext specified!"); } } else { if(createIfNotExist) { ContextualStorage contextualStorage = new ContextualStorage(beanManager, false, false); getDolphinSession().setAttribute(CLIENT_STORAGE_ATTRIBUTE, contextualStorage); return contextualStorage; } else { return null; } } }
/** * Create the holder/cache of the beans. * * @param listener A listener for changes to the cache */ ContextBeansHolder(ContextBeansListener listener) { this.listener = listener; if (this.listener == null) { this.listener = new ContextBeansListener() { @Override public void instanceRemoved(Contextual<?> bean, CreationalContext<?> context, Object instance) { } @Override public void instanceAdded(Contextual<?> bean, CreationalContext<?> context, Object instance) { } }; } }
@Override public <T> T get(final Contextual<T> component, final CreationalContext<T> creationalContext) { assertActive(); T instance = get(component); if (instance == null) { if (creationalContext != null) { Map<Contextual<?>, Object> componentInstanceMap = getComponentInstanceMap(); Map<Contextual<?>, CreationalContext<?>> creationalContextMap = getCreationalInstanceMap(); synchronized (componentInstanceMap) { instance = (T) componentInstanceMap.get(component); if (instance == null) { instance = component.create(creationalContext); if (instance != null) { componentInstanceMap.put(component, instance); creationalContextMap.put(component, creationalContext); } } } } } return instance; }
/** * We get PreDestroyViewMapEvent events from the JSF servlet and destroy our * contextual instances. This should (theoretically!) also get fired if the * webapp closes, so there should be no need to manually track all view * scopes and destroy them at a shutdown. * * @see javax.faces.event.SystemEventListener#processEvent(javax.faces.event.SystemEvent) */ @Override public void processEvent(final SystemEvent event) { if (event instanceof PreDestroyViewMapEvent) { Map<Contextual<?>, Object> componentInstanceMap = getComponentInstanceMap(); Map<Contextual<?>, CreationalContext<?>> creationalContextMap = getCreationalInstanceMap(); if (componentInstanceMap != null) { for (Map.Entry<Contextual<?>, Object> componentEntry : componentInstanceMap.entrySet()) { /* * No way to inform the compiler of type <T> information, so * it has to be abandoned here :( */ Contextual contextual = componentEntry.getKey(); Object instance = componentEntry.getValue(); CreationalContext creational = creationalContextMap.get(contextual); contextual.destroy(instance, creational); } } } }
/** * Determines whether the given bean is portlet or application scoped. * * @param bean The bean * @return <code>true</code> if the bean is portlet scoped */ public Boolean isPortletScoped(Contextual<?> bean) { PortletSessionScoped anno = context2Anno.get(bean); assert anno != null; boolean isPS = (anno.value() == PortletSession.PORTLET_SCOPE); if (isTrace) { StringBuilder txt = new StringBuilder(); txt.append("Bean: "); if (bean instanceof Bean<?>) { Bean<?> b = (Bean<?>) bean; txt.append(b.getBeanClass().getSimpleName()); } else { txt.append("Contextual"); } txt.append(", isPortletScoped: ").append(isPS); LOG.debug(txt.toString()); } return isPS; }
/** * Removes & destroys the given bean from the given bean map * @param bean */ @SuppressWarnings("unchecked") private <T> void remove(String id, Map<Contextual<?>, BeanInstance<?>> beanMap, Contextual<T> bean) { BeanInstance<?> bi = beanMap.get(bean); if (isDebug) { StringBuilder txt = new StringBuilder(80); txt.append("Removing bean: "); if (bean instanceof Bean<?>) { Bean<?> b = (Bean<?>) bean; txt.append(b.getBeanClass().getSimpleName()); } txt.append(", window ID: ").append(id); if (bi == null) { txt.append(", instance is null."); } LOG.debug(txt.toString()); } if (bi != null) { beans.remove(bean); bi.crco.release(); bean.destroy((T)bi.instance, (CreationalContext<T>)bi.crco); } }
/** * Session binding listener method - unbinding from session. * This occurs only when the session times out or is destroyed (in our case). * * @param arg0 */ @Override public void valueUnbound(HttpSessionBindingEvent evt) { if (isTrace) { LOG.trace("PortletSessionBeanHolder unbound from session. ID=" + evt.getName()); } synchronized(beans) { for (String id : beans.keySet()) { Map<Contextual<?>, BeanInstance<?>> beanMap = beans.get(id); for (Contextual<?> bean : beanMap.keySet()) { remove(id, beanMap, bean); } } beans.clear(); } }
/** * Removes & destroys the given bean * @param bean */ @SuppressWarnings("unchecked") protected <T> void remove(Contextual<T> bean) { BeanInstance<?> bi = beans.get(bean); if (isTrace) { StringBuilder txt = new StringBuilder(80); txt.append("Removing render state scoped bean: "); if (bean instanceof Bean<?>) { Bean<?> b = (Bean<?>) bean; txt.append(b.getBeanClass().getSimpleName()); } if (bi == null) { txt.append(", instance is null."); } LOG.trace(txt.toString()); } if (bi != null) { beans.remove(bean); bi.crco.release(); bean.destroy((T)bi.instance, (CreationalContext<T>)bi.crco); } }
/** * Remove & destroy all beans. if a response is provided, store the bean state. * * @param resp The state aware response */ protected void removeAll(StateAwareResponse resp) { for (Contextual<?> bean : beans.keySet()) { if (resp != null) { PortletSerializable thisBean = (PortletSerializable) beans.get(bean).instance; String[] vals = thisBean.serialize(); String pn = config.getParamName((Bean<?>) bean); resp.getRenderParameters().setValues(pn, vals); if (isTrace) { StringBuilder txt = new StringBuilder(128); txt.append("Stored parameter for portlet with namespace: "); txt.append(resp.getNamespace()); txt.append(", paramName: ").append(pn); txt.append(", Values: ").append(Arrays.toString(vals)); LOG.trace(txt.toString()); } } remove(bean); } }
@Override public <T> T get(Contextual<T> bean, CreationalContext<T> crco) { PortletSessionBeanHolder holder = PortletSessionBeanHolder.getBeanHolder(); if (holder == null) { throw new ContextNotActiveException("The portlet session context is not active."); } T inst = holder.getBean(bean); if (inst == null) { inst = bean.create(crco); holder.putBeanInstance(bean, crco, inst); } return inst; }
/** * Returns an instance for the contextual type. If no existing bean is available, * a new instance is created. * * @param bean Contextual type (Bean) for which an instance is desired * @return The instance, or null if none exists */ @SuppressWarnings("unchecked") public <T> T getBean(Contextual<T> bean, CreationalContext<T> crco) { BeanInstance<?> bi = beans.get(bean); if (bi == null) { // No bean available, so create one. BeanInstance<T> newbi = new BeanInstance<T>(); newbi.crco = crco; newbi.instance = bean.create(crco); bi = newbi; beans.put(bean, newbi); if (isTrace) { StringBuilder txt = new StringBuilder(80); txt.append("Created bean: "); txt.append(((Bean<?>) bean).getBeanClass().getSimpleName()); LOG.trace(txt.toString()); } } return (T) bi.instance; }
/** * Removes & destroys the given bean * @param bean */ @SuppressWarnings("unchecked") protected <T> void remove(Contextual<T> bean) { BeanInstance<?> bi = beans.get(bean); if (isTrace) { StringBuilder txt = new StringBuilder(80); txt.append("Removing portlet request scoped bean: "); if (bean instanceof Bean<?>) { Bean<?> b = (Bean<?>) bean; txt.append(b.getBeanClass().getSimpleName()); } if (bi == null) { txt.append(", instance is null."); } LOG.trace(txt.toString()); } if (bi != null) { beans.remove(bean); bi.crco.release(); bean.destroy((T)bi.instance, (CreationalContext<T>)bi.crco); } }
/** * Tries to add the bean in the context so it is reloaded in the next activation of the context. * * @param ctx * @param managedBean * @return */ @SuppressWarnings("unchecked") public static boolean addToReloadSet(Context ctx, Contextual<?> managedBean) { try { LOGGER.debug("Adding bean '{}' to context '{}'", managedBean, ctx.getClass()); Field toRedefine = ctx.getClass().getField("$$ha$toReloadOwb"); Set toReload = Set.class.cast(toRedefine.get(ctx)); if (toReload == null) { toReload = new HashSet(); toRedefine.set(ctx, toReload); } toReload.add(managedBean); return true; } catch(Exception e) { LOGGER.warning("Context '{}' is not patched. Can not add bean '{}' to reload set", e, ctx, managedBean); } return false; }
/** * Will remove bean from context forcing a clean new instance to be created (eg calling post-construct) * * @param ctx * @param managedBean */ static void destroy(OwbHotswapContext ctx, Contextual<?> managedBean ) { try { LOGGER.debug("Removing bean '{}' from context '{}'", managedBean, ctx); Object get = ctx.get(managedBean); if (get != null) { ctx.destroy(managedBean); } get = ctx.get(managedBean); if (get != null) { LOGGER.error("Error removing ManagedBean '{}', it still exists as instance '{}'", managedBean, get); ctx.destroy(managedBean); } } catch (Exception e) { LOGGER.error("Error destoying bean '{}' in context '{}'", e, managedBean, ctx); } }
/** * Will re-inject any managed beans in the target. Will not call any other life-cycle methods * * @param ctx * @param managedBean */ @SuppressWarnings("unchecked") static void reinitialize(Context ctx, Contextual<Object> contextual) { try { ManagedBean<Object> managedBean = ManagedBean.class.cast(contextual); LOGGER.debug("Re-Initializing bean '{}' in context '{}'", managedBean, ctx); Object get = ctx.get(managedBean); if (get != null) { LOGGER.debug("Bean injection points are reinitialized '{}'", managedBean); CreationalContextImpl<Object> creationalContext = managedBean.getWebBeansContext().getCreationalContextFactory().getCreationalContext(managedBean); managedBean.getProducer().inject(get, creationalContext); } } catch (Exception e) { LOGGER.error("Error reinitializing bean '{}' in context '{}'", e, contextual, ctx); } }
/** * Tries to add the bean in the context so it is reloaded in the next activation of the context. * * @param ctx * @param managedBean * @return */ public static boolean addToReloadSet(Context ctx, Contextual<Object> managedBean) { try { LOGGER.debug("Adding bean in '{}' : {}", ctx.getClass(), managedBean); Field toRedefine = ctx.getClass().getDeclaredField("$$ha$toReloadWeld"); Set toReload = Set.class.cast(toRedefine.get(ctx)); if (toReload == null) { toReload = new HashSet(); toRedefine.set(ctx, toReload); } toReload.add(managedBean); return true; } catch(Exception e) { LOGGER.warning("Context {} is not patched. Can not add {} to reload set", e, ctx, managedBean); } return false; }
/** * Will remove bean from context forcing a clean new instance to be created (eg calling post-construct) * * @param ctx * @param managedBean */ public static void destroy(WeldHotswapContext ctx, Contextual<?> managedBean ) { try { LOGGER.debug("Removing Contextual from Context........ {},: {}", managedBean, ctx); Object get = ctx.get(managedBean); if (get != null) { ctx.destroy(managedBean); } get = ctx.get(managedBean); if (get != null) { LOGGER.error("Error removing ManagedBean {}, it still exists as instance {} ", managedBean, get); ctx.destroy(managedBean); } } catch (Exception e) { LOGGER.error("Error destoying bean {},: {}", e, managedBean, ctx); } }
/** * Retrieves the map that contains transaction scoped beans for the current * transaction. * * @param a bean that implements {@link TransactionSupport}. * @return instances of transaction scoped beans for the current * transaction. */ private <T> Map<Contextual<T>, ContextualInstance<T>> getInstances( TransactionSupport transactionSupport) { @SuppressWarnings("unchecked") Map<Contextual<T>, ContextualInstance<T>> instances = (Map<Contextual<T>, ContextualInstance<T>>) transactionSupport .getResource(TRANSACTION_BEANS_KEY); if (instances == null) { instances = new HashMap<Contextual<T>, ContextualInstance<T>>(); transactionSupport.putResource(TRANSACTION_BEANS_KEY, instances); registerSynchronization(transactionSupport, instances); } return instances; }
public void setWebBeansContext(final WebBeansContext webBeansContext) { this.webBeansContext = webBeansContext; if (webBeansContext == null) { return; } if (!WebappWebBeansContext.class.isInstance(webBeansContext)) { cacheProxies = new ConcurrentHashMap<Contextual<?>, Object>(); } else { // share cache of proxies between the whole app otherwise hard to share an EJB between a webapp and the lib part of the app final WebBeansContext parent = WebappWebBeansContext.class.cast(webBeansContext).getParent(); if (parent != null) { cacheProxies = CdiPlugin.class.cast(parent.getPluginLoader().getEjbPlugin()).cacheProxies; } else { cacheProxies = new ConcurrentHashMap<Contextual<?>, Object>(); } } }
private Map<Contextual<?>, BeanInstanceBag<?>> findMap() { final Object resource; try { // we can't call registry.getResource(KEY) in afterCompletion resource = context.geronimoTxMgr ? TransactionImpl.class.cast(context.transactionManager.getTransaction()).getResource(KEY): registry.getResource(KEY); } catch (final SystemException e) { throw new IllegalStateException(e); } if (resource == null) { final Map<Contextual<?>, BeanInstanceBag<?>> map = new HashMap<>(); registry.putResource(KEY, map); registry.registerInterposedSynchronization(context); return map; } return Map.class.cast(resource); }
@Override public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext) { checkArgumentNotNull(contextual); Map<Contextual<?>, ContextualInstance<?>> ctx = currentContext.get(); if (ctx == null) { throw new ContextNotActiveException(); } @SuppressWarnings("unchecked") ContextualInstance<T> instance = (ContextualInstance<T>) ctx.get(contextual); if (instance == null && creationalContext != null) { instance = new ContextualInstance<T>(contextual.create(creationalContext), creationalContext, contextual); ctx.put(contextual, instance); } return instance != null ? instance.get() : null; }
void destroy(MustacheRenderingEvent event) { Map<Contextual<?>, ContextualInstance<?>> ctx = currentContext.get(); if (ctx == null) { LOGGER.warn("Cannot destroy context - current context is null"); return; } LOGGER.debug("Rendering finished - destroy context [template: {}]", event.getMustacheName()); for (ContextualInstance<?> instance : ctx.values()) { try { LOGGER.trace("Destroying contextual instance [contextual: {}]", instance.getContextual()); instance.destroy(); } catch (Exception e) { LOGGER.warn("Unable to destroy instance" + instance.get() + " for bean: " + instance.getContextual()); } } ctx.clear(); currentContext.remove(); }
@SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testCreateNewInstanceAndSubsequentRetrievalOfExistingObject() { CreationalContext creationalContext = mock(CreationalContext.class); Contextual contextual = mock(Contextual.class); when(contextual.create(creationalContext)).thenReturn("test"); Object result = JoynrJeeMessageContext.getInstance().get(contextual, creationalContext); assertNotNull(result); assertEquals("test", result); verify(contextual).create(creationalContext); assertEquals("test", JoynrJeeMessageContext.getInstance().get(contextual)); reset(contextual); reset(creationalContext); assertEquals("test", JoynrJeeMessageContext.getInstance().get(contextual, creationalContext)); verify(contextual, never()).create(creationalContext); }
@Override public <T> T get(final Contextual<T> component, final CreationalContext<T> creationalContext) { checkActive(); final ConcurrentMap<Contextual<?>, Instance<?>> storage = getOrCreateCurrentStorage(); Instance<T> instance = (Instance<T>) storage.get(component); if (instance == null) { synchronized (this) { instance = (Instance<T>) storage.get(component); if (instance == null) { final T value = component.create(creationalContext); instance = new Instance<T>(value, creationalContext); storage.putIfAbsent(component, instance); } } } return instance.value; }