How to specify the default scope in Spring's a

2019-07-31 10:29发布

问题:

I want to make all beans request scoped by default, however the Spring documentation says that the default scope is Singleton. (sections 3.4.1 and 3.4.2 http://static.springsource.org/spring/docs/2.5.x/reference/beans.html)

I want to declare the default scope to be request scoped.

This is the closest thing I have found so far -- it's a defect that has not been touched in some time. jira.springframework.org/browse/SPR-4994?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel#issue-tabs

回答1:

There is no default-scope Attribute defined in spring-beans.xsd file. But according To BeanDefinition API

Extended bean factories might support further scopes.

And WebApplicationContext - A extended ApplicationContext supports request scope

Supported in addition to the standard scopes "singleton" and "prototype"

So just make sense To use request scope when you have a WebApplicationContext. And if you want To register of all beans defined in WebApplicationContext as request scoped, you must define a BeanFactoryPostProcessor

public class RequestScopedPostProcessor implements BeanFactoryPostProcessor {

    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
        for(String beanName: factory.getBeanDefinitionNames()) {
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);

            beanDefinition.setScope("request");
        }
    }
}

And do not forget register your BeanFactoryPostProcessor

<bean class="RequestScopedPostProcessor"/>

But keep in mind

This method does not consider ancestor factories. It is only meant for accessing local bean definitions of this factory

So The BeanFactoryPostProcessor defined above just overrides scope property whether your bean is defined in your WebApplicationContext

UPDATE

is there a way to then override some of the default "request" scoped beans to be singleton scope ?

Again you should use The same BeanFactoryPostProcessor provided above. I am not sure but I Think The only way you can set up its scope is by using beanDefinition.setScope method. And There is a lot of useful methods you can retrieve information about any bean. See ConfigurableListableBeanFactory such as

  • getBeanNamesForType

...

/**
  * Suppose Service is an interface
  *
  * And you want to define all of Service implementations as singleton
  */
String [] beanNameArray = factory.getBeanNamesForType(Service.class);
for(String beanName: beanNameArray) {
    BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);

    beanDefinition.setScope("singleton");
}

I hope It can be useful