`
234390216
  • 浏览: 10246409 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:463244
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1776674
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1399424
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:395312
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:680420
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:531492
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1186032
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:470046
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151783
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68574
社区版块
存档分类
最新评论

Spring(10)——bean作用范围(二)—自定义scope

阅读更多

10.7 自定义Scope

如果用户觉得Spring内置的几种Scope不能满足需求,则可以定制自己的Scope,即实现自己的org.springframework.beans.factory.config.Scope。Scope接口定义了如下几个方法,详情请参看Spring的API文档。

public interface Scope {

	Object get(String name, ObjectFactory<?> objectFactory);

	Object remove(String name);

	void registerDestructionCallback(String name, Runnable callback);

	Object resolveContextualObject(String key);

	String getConversationId();

}

下面来看一下Spring内部Scope为application的定义,即ServletContextScope的定义。

public class ServletContextScope implements Scope, DisposableBean {

	private final ServletContext servletContext;

	private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>();


	/**
	 * Create a new Scope wrapper for the given ServletContext.
	 * @param servletContext the ServletContext to wrap
	 */
	public ServletContextScope(ServletContext servletContext) {
		Assert.notNull(servletContext, "ServletContext must not be null");
		this.servletContext = servletContext;
	}


	@Override
	public Object get(String name, ObjectFactory<?> objectFactory) {
		Object scopedObject = this.servletContext.getAttribute(name);
		if (scopedObject == null) {
			scopedObject = objectFactory.getObject();
			this.servletContext.setAttribute(name, scopedObject);
		}
		return scopedObject;
	}

	@Override
	public Object remove(String name) {
		Object scopedObject = this.servletContext.getAttribute(name);
		if (scopedObject != null) {
			this.servletContext.removeAttribute(name);
			this.destructionCallbacks.remove(name);
			return scopedObject;
		}
		else {
			return null;
		}
	}

	@Override
	public void registerDestructionCallback(String name, Runnable callback) {
		this.destructionCallbacks.put(name, callback);
	}

	@Override
	public Object resolveContextualObject(String key) {
		return null;
	}

	@Override
	public String getConversationId() {
		return null;
	}


	/**
	 * Invoke all registered destruction callbacks.
	 * To be called on ServletContext shutdown.
	 * @see org.springframework.web.context.ContextCleanupListener
	 */
	@Override
	public void destroy() {
		for (Runnable runnable : this.destructionCallbacks.values()) {
			runnable.run();
		}
		this.destructionCallbacks.clear();
	}

}

10.7.1 注册

自定义了Scope之后我们得在Spring中进行注册,好让Spring能够对其进行识别,这样我们才能在进行对应bean定义的时候使用自定义的Scope。自定义Scope的注册有两种方式,一种是程序化的,一种是通过XML进行配置的。
我们先来实现一个自定义的Scope供注册自定义Scope使用。

public class MyScope implements Scope {
	
	private Map<String, Object> beanMap = new ConcurrentHashMap<String, Object>();

	/**
	 * 获取指定beanName的bean实例
	 * @param name 对应bean的beanName
	 * @param objectFactory 可以产生对应bean实例的ObjectFactory
	 * @return 获取到的实例
	 */
	public Object get(String name, ObjectFactory<?> objectFactory) {
		System.out.println("------------get-----------" + name);
		synchronized (this) {
			if (!beanMap.containsKey(name)) {
				System.out.println("-----------not--exists-------" + name);
				beanMap.put(name, objectFactory.getObject());
			}
		}
		return beanMap.get(name);
	}

	/**
	 * 底层移除name对应的对象。实现者需要同时移除注册的销毁化回调方法
	 * @param name
	 * @return 移除的对象
	 */
	public Object remove(String name) {
		return beanMap.remove(name);
	}

	/**
	 * 注册一个销毁时的回调方法
	 * @param name
	 * @param callback
	 */
	public void registerDestructionCallback(String name, Runnable callback) {

	}

	public Object resolveContextualObject(String key) {
		return null;
	}

	public String getConversationId() {
		return null;
	}

}

程序化注册自定义Scope是通过ConfigurableBeanFactory的registerScope()方法进行的,其对应定义如下,scopeName表示我们需要注册的scope的名称,第二个参数Scope表示我们需要注册的Scope的一个实例。

	/**
	 * Register the given scope, backed by the given Scope implementation.
	 * @param scopeName the scope identifier
	 * @param scope the backing Scope implementation
	 */
	void registerScope(String scopeName, Scope scope);

我们可以通过常用的ApplicationContext,如ClassPathXmlApplicationContext等的getBeanFactory()方法就能获取到对应的ConfigurableBeanFactory对象,然后进行注册。如:

	ClassPathXmlApplicationContext context = ...;
	context.getBeanFactory().registerScope("myScope", new MyScope());

通过XML配置进行注册是指通过在Spring的配置文件中定义一个CustomScopeConfigurer类型的bean,并通过其setScopes()方法注入自定义Scope。如下所示,我们通过XML配置注册了一个名叫myScope的Scope定义。

	<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
		<property name="scopes">
			<map>
				<entry key="myScope">
					<bean class="com.app.MyScope"/>
				</entry>
			</map>
		</property>
	</bean>

之后就可以在定义bean的时候使用我们自己定义的myScope来作为bean定义的Scope了。

	<bean id="hello" class="com.app.Hello" scope="myScope"/>

在上述配置中我们指定了id为hello的bean定义的scope为自定义的myScope。之后运行如下测试代码,我们可以看到控制台的输出过程。我们每从bean容器中获取一次hello的实例,对应MyScope的get()方法就会被调用一次。

	@org.junit.Test
	public void test() {
		System.out.println(context.getBean("hello"));
		System.out.println(context.getBean("hello"));
	}

(注:本文是基于Spring4.1.0所写)

 

0
0
分享到:
评论

相关推荐

    尚学堂_Spring_0600_IOC_Bean_Scope

    此外,Spring还提供了自定义Scope的机制,开发者可以根据需求定义自己的Bean作用域。 为了深入学习这个主题,可以参考提供的博文链接(虽然这里没有给出具体的链接内容,通常这些链接会包含博主的个人理解和实践...

    撸一撸Spring Framework-IoC-BeanDefinition(csdn)————程序.pdf

    它解析`&lt;bean&gt;`标签,从中提取出`class`属性(定义bean的实现类)、`parent`属性(定义父bean)、以及其他的属性,如`scope`(作用域)、`abstract`(是否为抽象bean)、`lazy-init`(是否延迟初始化)、`autowire`...

    spring基础实例源码

    Spring允许开发者定义bean的初始化方法和销毁方法,以实现自定义的生命周期行为。此外,还涉及了bean的生命周期状态,如单例bean的实例化时机以及原型bean的每次请求都会创建新实例等。 2. **Spring_0700_IOC_...

    Spring-IOC丐版

    4. **Scope**: Bean的作用域,比如单例(Singleton)、原型(Prototype)等,决定了Bean的实例化策略。 5. **Bean的查找和引用**: 容器提供了获取Bean实例的方法,以及在Bean之间引用其他Bean的能力。 通过分析这...

    spring ioc

    标题“spring ioc”指的是Spring框架中的核心特性——Inversion of Control(控制反转),也称为依赖注入(Dependency Injection)。在Spring框架中,IOC是通过容器来管理对象的生命周期和对象之间的依赖关系,使得...

    Spring学习笔记系列之三

    本篇我们将聚焦于"Spring学习笔记系列之三"中的关键知识点——SpringMVC的源码分析,特别是父子容器的启动原理。这个主题是理解Spring MVC工作流程、定制化配置以及优化应用程序性能的关键。 首先,我们要明白...

    spring概述

    Spring 还支持自定义 Scope,如 Singleton(单例)、Prototype(原型)、Request(请求)、Session(会话)等。 4. **数据访问集成**:Spring 对各种数据访问技术提供了集成,包括 JDBC、JPA、Hibernate、MyBatis ...

    spring重点知识_ioc_springjava_aop_

    此外,`@Autowired`注解用于自动装配bean的依赖,`@Qualifier`用于指定特定的bean,`@Scope`控制bean的作用域,`@PostConstruct`和`@PreDestroy`标记初始化和销毁方法。 **总结** Spring框架的IOC和AOP机制极大地...

    Spring的IoC容器(PDF)

    - bean的作用域:通过`scope`属性定义bean的生命周期,例如单例(singleton)或多例(prototype)。 - 工厂方法与FactoryBean:通过工厂方法或FactoryBean接口创建bean,增强bean的创建机制。 - 替换机制:通过`...

    pring配置文件共5页.pdf.zip

    《Spring配置文件详解——共五页》 在Java开发领域,Spring框架无疑是最为重要的工具之一,它以其强大的依赖注入和面向切面编程能力,极大地简化了企业级应用的开发。本篇文档将深入探讨Spring配置文件的核心概念,...

    自学b站黑马ssm框架思维导图XMind笔记

    - 生命周期管理:包括初始化、正常使用和销毁三个阶段,Spring提供了回调方法、Scope(作用域)和生命周期接口等进行管理。 3. **04依赖注入.xmind** —— 依赖注入的详细操作 - XML配置注入:通过`&lt;bean&gt;`标签...

    spring框架案例学习文档笔记

    - **模拟目标**:本节主要是理解Spring框架的核心功能——依赖注入(Dependency Injection, DI),并通过自定义的方式模拟其实现。 - **DI概念**:DI是一种软件设计模式,它提倡将组件之间的依赖关系由外部注入,而...

    SpringSide4

    通过@Scope注解控制Bean的作用域,如单例(singleton)或多例(prototype)。此外,还可以通过BeanPostProcessor和InitializingBean接口自定义Bean的初始化和销毁逻辑。 6. **AOP代理**:Spring支持JDK动态代理和...

    multicampus-project-spring

    此外,还可以通过`scope`属性来指定Bean的作用域。同时,我们还会接触到生命周期回调方法,如`@PostConstruct`和`@PreDestroy`注解,它们允许我们在Bean初始化和销毁时执行特定操作。 在多校园项目的背景下,Spring...

    java或Java框架中常用的注解及其作用详解_资料.docx

    - `@Scope`:定义Bean的作用域,如单例(`singleton`)或原型(`prototype`)。 - `@Lazy`:标记Bean为懒加载,意味着只有在首次请求时才会初始化。 - `@PostConstruct`和`@PreDestroy`:分别标记初始化方法和销毁...

    springboot搭建

    SpringBoot 搭建——整合 Redis 与 MyBatis 的实战指南 在现代的 Java 开发中,Spring Boot 已经成为了快速构建应用的首选框架,它极大地简化了 Spring 应用的初始设置和配置。本教程将详细介绍如何使用 Spring ...

    SpringBasicsAnnotation:具有基于注释的配置的样本Spring核心概念

    除了基本的bean注解,还有其他一些常用的注解,比如`@Value`用于注入属性值,`@Qualifier`用于在多个相同类型的bean中指定注入哪一个,`@Scope`用于定义bean的作用范围,如单例(singleton)或原型(prototype)等。...

Global site tag (gtag.js) - Google Analytics