@Override public void destroyScopedBean(String beanName) { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); if (mbd.isSingleton() || mbd.isPrototype()) { throw new IllegalArgumentException( "Bean name '" + beanName + "' does not correspond to an object in a mutable scope"); } String scopeName = mbd.getScope(); Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope SPI registered for scope '" + scopeName + "'"); } Object bean = scope.remove(beanName); if (bean != null) { destroyBean(beanName, bean, mbd); } }
/** * Add the given bean to the list of disposable beans in this factory, * registering its DisposableBean interface and/or the given destroy method * to be called on factory shutdown (if applicable). Only applies to singletons. * @param beanName the name of the bean * @param bean the bean instance * @param mbd the bean definition for the bean * @see RootBeanDefinition#isSingleton * @see RootBeanDefinition#getDependsOn * @see #registerDisposableBean * @see #registerDependentBean */ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
@Override public void registerScope(String scopeName, Scope scope) { Assert.notNull(scopeName, "Scope identifier must not be null"); Assert.notNull(scope, "Scope must not be null"); if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) { throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'"); } Scope previous = this.scopes.put(scopeName, scope); if (previous != null && previous != scope) { if (logger.isInfoEnabled()) { logger.info("Replacing scope '" + scopeName + "' from [" + previous + "] to [" + scope + "]"); } } else { if (logger.isDebugEnabled()) { logger.debug("Registering scope '" + scopeName + "' with implementation [" + scope + "]"); } } }
@Override public void destroyScopedBean(String beanName) { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); if (mbd.isSingleton() || mbd.isPrototype()) { throw new IllegalArgumentException( "Bean name '" + beanName + "' does not correspond to an object in a mutable scope"); } String scopeName = mbd.getScope(); Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope SPI registered for scope name '" + scopeName + "'"); } Object bean = scope.remove(beanName); if (bean != null) { destroyBean(beanName, bean, mbd); } }
/** * Add the given bean to the list of disposable beans in this factory, * registering its DisposableBean interface and/or the given destroy method * to be called on factory shutdown (if applicable). Only applies to singletons. * @param beanName the name of the bean * @param bean the bean instance * @param mbd the bean definition for the bean * @see RootBeanDefinition#isSingleton * @see RootBeanDefinition#getDependsOn * @see #registerDisposableBean * @see #registerDependentBean */ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
@Test public void doesNotReplaceExistingScopes() throws Exception { // gh-2082 Scope scope = mock(Scope.class); ConfigurableListableBeanFactory factory = this.context.getBeanFactory(); factory.registerScope(WebApplicationContext.SCOPE_REQUEST, scope); factory.registerScope(WebApplicationContext.SCOPE_SESSION, scope); factory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, scope); addEmbeddedServletContainerFactoryBean(); this.context.refresh(); assertThat(factory.getRegisteredScope(WebApplicationContext.SCOPE_REQUEST)) .isSameAs(scope); assertThat(factory.getRegisteredScope(WebApplicationContext.SCOPE_SESSION)) .isSameAs(scope); assertThat(factory.getRegisteredScope(WebApplicationContext.SCOPE_GLOBAL_SESSION)) .isSameAs(scope); }
@SuppressWarnings("unchecked") protected Object _get(Map map, String name, ObjectFactory factory, boolean registerCb) { Object o = map.get(name); if(o == null) { o = factory.getObject(); map.put(name, o); if(registerCb && defaultDestructionCallback != null) { try { Constructor c = defaultDestructionCallback.getConstructor(Scope.class,String.class); registerDestructionCallback(name, (Runnable) c.newInstance(this,name)); } catch(Exception e) { log.error("Could not setup destruction callback: " + name, e); } } } return o; }
@Test public void doesNotReplaceExistingScopes() throws Exception { // gh-2082 Scope scope = mock(Scope.class); ConfigurableListableBeanFactory factory = this.context.getBeanFactory(); factory.registerScope(WebApplicationContext.SCOPE_REQUEST, scope); factory.registerScope(WebApplicationContext.SCOPE_SESSION, scope); factory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, scope); addEmbeddedServletContainerFactoryBean(); this.context.refresh(); assertThat(factory.getRegisteredScope(WebApplicationContext.SCOPE_REQUEST), sameInstance(scope)); assertThat(factory.getRegisteredScope(WebApplicationContext.SCOPE_SESSION), sameInstance(scope)); assertThat(factory.getRegisteredScope(WebApplicationContext.SCOPE_GLOBAL_SESSION), sameInstance(scope)); }
public void destroyScopedBean(String beanName) { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); if (mbd.isSingleton() || mbd.isPrototype()) { throw new IllegalArgumentException( "Bean name '" + beanName + "' does not correspond to an object in a mutable scope"); } String scopeName = mbd.getScope(); Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope SPI registered for scope '" + scopeName + "'"); } Object bean = scope.remove(beanName); if (bean != null) { destroyBean(beanName, bean, mbd); } }
private void cleanOsgiBundleScope(ConfigurableListableBeanFactory beanFactory) { Scope scope = beanFactory.getRegisteredScope(OsgiBundleScope.SCOPE_NAME); if (scope != null && scope instanceof OsgiBundleScope) { if (logger.isDebugEnabled()) logger.debug("Destroying existing bundle scope beans..."); ((OsgiBundleScope) scope).destroy(); } }
@Override public void registerScope(String scopeName, Scope scope) { Assert.notNull(scopeName, "Scope identifier must not be null"); Assert.notNull(scope, "Scope must not be null"); if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) { throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'"); } this.scopes.put(scopeName, scope); }
public ExistingWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) { this.beanFactory = beanFactory; for (String scopeName : SCOPES) { Scope scope = beanFactory.getRegisteredScope(scopeName); if (scope != null) { this.scopes.put(scopeName, scope); } } }
public void restore() { for (Map.Entry<String, Scope> entry : this.scopes.entrySet()) { if (logger.isInfoEnabled()) { logger.info("Restoring user defined scope " + entry.getKey()); } this.beanFactory.registerScope(entry.getKey(), entry.getValue()); } }
@Override public void prepareTestInstance(TestContext testContext) throws Exception { if (testContext.getApplicationContext() instanceof GenericApplicationContext) { GenericApplicationContext context = (GenericApplicationContext) testContext.getApplicationContext(); ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); Scope requestScope = new SimpleThreadScope(); beanFactory.registerScope("request", requestScope); Scope sessionScope = new SimpleThreadScope(); beanFactory.registerScope("session", sessionScope); } }
/** * Returns a property value for the bean with the given name from the dictionary. * * @param beanName id or name for the bean definition * @param propertyName name of the property to retrieve, must be a valid property configured on * the bean definition * @return Object property value for property */ public Object getDictionaryBeanProperty(String beanName, String propertyName) { Object bean = ddBeans.getSingleton(beanName); if (bean != null) { return ObjectPropertyUtils.getPropertyValue(bean, propertyName); } BeanDefinition beanDefinition = ddBeans.getMergedBeanDefinition(beanName); if (beanDefinition == null) { throw new RuntimeException("Unable to get bean for bean name: " + beanName); } PropertyValues pvs = beanDefinition.getPropertyValues(); if (pvs.contains(propertyName)) { PropertyValue propertyValue = pvs.getPropertyValue(propertyName); Object value; if (propertyValue.isConverted()) { value = propertyValue.getConvertedValue(); } else if (propertyValue.getValue() instanceof String) { String unconvertedValue = (String) propertyValue.getValue(); Scope scope = ddBeans.getRegisteredScope(beanDefinition.getScope()); BeanExpressionContext beanExpressionContext = new BeanExpressionContext(ddBeans, scope); value = ddBeans.getBeanExpressionResolver().evaluate(unconvertedValue, beanExpressionContext); } else { value = propertyValue.getValue(); } return value; } return null; }
public void registerScope(String scopeName, Scope scope) { Assert.notNull(scopeName, "Scope identifier must not be null"); Assert.notNull(scope, "Scope must not be null"); if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) { throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'"); } this.scopes.put(scopeName, scope); }
@Override public Scope getRegisteredScope(String scopeName) { Assert.notNull(scopeName, "Scope identifier must not be null"); return this.scopes.get(scopeName); }
public DefaultScopeDesctructionCallback(Scope scope, String name) { super(scope, name); }
public Scope getRegisteredScope(String scopeName) { Assert.notNull(scopeName, "Scope identifier must not be null"); return this.scopes.get(scopeName); }
/** * Evaluate the given String as contained in a bean definition, * potentially resolving it as an expression. * @param value the value to check * @param beanDefinition the bean definition that the value comes from * @return the resolved value * @see #setBeanExpressionResolver */ protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) { if (this.beanExpressionResolver == null) { return value; } Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null); return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope)); }
/** * Construct the Callback with the {@link Scope} and bean name * * @param scope The {@link Scope} the destruction callback runs under * @param name The name of the bean */ public AbstractScopeDestructionCallback(Scope scope, String name) { this.scope = scope; this.name = name; }