问答详情
源自:4-3 Spring Bean装配之Autowired注解说明-2

Bean的作用域

Bean的作用域不是singleton,容器中只有一个实例,那么如果在BeanImplOne和BeanImplTwo里个有一个BeanInterfarce的对象。那么在BeanImplOne中,对它的BeanInterfac中的属性做更改,在BeanImplTwo里的BeanInterface实例相应属性的值也是会更改的么?

还是不会改变? 不会改变是什么原因,这是容器里一个Bean的实例的不同拷贝么?

提问者:Bluewind001 2015-09-06 20:44

个回答

  • Kirshry
    2015-10-02 13:01:18
    已采纳

    变还是不变得看对应的那个对象的Scope。估计你是对scope有点疑惑,spring中每个scope类都实现了org.springframework.beans.factory.config.Scope接口,然后注册到org.springframework.beans.factory.config.CustomScopeConfigurer中。每次获取bean的时候底层都是访问Scope来获取的,你也可以定义自己的Scope。比如

    public class ThreadScope implements org.springframework.beans.factory.config.Scope {
        private final ThreadLocal<Map<String, Object>> SCOPE_THREAD = new ThreadLocal() {
            @Override
            protected Object initialValue() {
                return new HashMap<String, Object>();
            }
        };
    
        @Override
        public Object get(String name, ObjectFactory<?> objectFactory) {
            if (SCOPE_THREAD.get().containsKey(name)) {
                return SCOPE_THREAD.get().get(name);
            }
            SCOPE_THREAD.get().put(name, objectFactory.getObject());
            return SCOPE_THREAD.get().get(name);
        }
    
        @Override
        public Object remove(String name) {
            return SCOPE_THREAD.get().remove(name);
        }
    
        //空实现代表不让spring容器管理bean
        @Override
        public void registerDestructionCallback(String s, Runnable runnable) {
    
        }
    
        @Override
        public Object resolveContextualObject(String s) {
            return null;
        }
    
        @Override
        public String getConversationId() {
            return null;
        }
    }

    然后注册:

    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="thread">
                    <bean class="xx.xx.xx.ThreadScope"></bean>
                </entry>
            </map>
        </property>
    </bean>

    这样就OK了,这个Scope就是每个线程的bean都是同一个