spring核心技术(1)

#spring核心技术

## 基本原理-容器和bean

1、在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean。 简单地讲,bean就是由Spring容器初始化、装配及管理的对象。

2、org.springframework.beans.factory.BeanFactory 是Spring IoC容器的实际代表者,IoC容器负责容纳此前所描述的bean,并对bean进行管理。

3、在Spring中,BeanFactory是IoC容器的核心接口。 它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

4、ApplicationContext在WEB应用中的实例化

<context-param>
	  <param-name>contextConfigLocation</param-name>
	  <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
	</context-param>

	<listener>
	  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

 ContextLoaderListener首先检查contextConfigLocation参数,如果它不存在,它将使用/WEB-INF/applicationContext.xml作为默认值。如果已存在,它将使用分隔符(逗号、冒号或空格)将字符串分解成应用上下文件位置路径。

5、实例化容器

ApplicationContext context = new ClassPathXmlApplicationContext(
		new String[] {"services.xml", "daos.xml"});

## 依赖

1、依赖注入(DI)背后的基本原理是对象之间的依赖关系(即一起工作的其它对象)只会通过以下几种方式来实现:Setter注入和构造器注入。因此,容器的工作就是创建bean时注入那些依赖关系。

2、循环依赖

(1)构造器的循环依赖 

(2)field属性的循环依赖

构造器的循环依赖问题无法解决,只能拋出BeanCurrentlyInCreationException异常,在解决属性循环依赖时,spring采用的是提前暴露对象的方法。

Spring的循环依赖的理论依据基于Java的引用传递,当获得对象的引用时,对象的属性是可以延后设置的(但是构造器必须是在获取引用之前)。

3、static工厂方法返回对象实例

<bean id="exampleBean" class="examples.ExampleBean"
		  factory-method="createInstance">
	  <constructor-arg ref="anotherExampleBean"/>
	  <constructor-arg value="1"/> 
	</bean>
	<bean id="anotherExampleBean" class="examples.AnotherBean"/>
public class ExampleBean {
		// a private constructor
		private ExampleBean(...) {
		  ...
		}
		public static ExampleBean createInstance (
            AnotherBean anotherBean, int i) {
			ExampleBean eb = new ExampleBean (...);
			// some other operations...
			return eb;
		}
	}

 请注意,传给static工厂方法的参数由constructor-arg元素提供,这与使用构造器注入时完全一样。

## bean的作用域

singleton:在每个Spring IoC容器中一个bean定义对应一个对象实例。

prototype:一个bean定义对应多个对象实例。

request:在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。

session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

global session:在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。

1、根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。

2、request、session以及global session 仅在基于web的应用中使用,如果你用Spring Web MVC,即用SpringDispatcherServlet或DispatcherPortlet来处理请求,则不需要做特别的配置:DispatcherServlet 和 DispatcherPortlet已经处理了所有有关的状态,否则需要在Web应用的'web.xml'文件中增加 javax.servlet.ServletRequestListener 定义

<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>

## 定制bean特性

### 生命周期回调

1、Spring提供了几个标志接口(marker interface),这些接口用来改变容器中bean的行为;它们包括InitializingBean

和DisposableBean。实现这两个接口的bean在初始化和析构时容器会调用前者的afterPropertiesSet()方法,

以及后者的destroy()方法。

2、Spring在内部使用BeanPostProcessor实现来处理它能找到的任何标志接口并调用相应的方法。

如果你需要自定义特性或者生命周期行为,你可以实现自己的 BeanPostProcessor。

### 初始化回调

1、实现org.springframework.beans.factory.InitializingBean接口允许容器在设置好bean的所有必要属性后,执行初始化事宜。

InitializingBean接口仅指定了一个方法

void afterPropertiesSet() throws Exception;

  2、通常,要避免使用InitializingBean接口并且不鼓励使用该接口,因为这样会将代码和Spring耦合起来。

有一个可选的方案是,可以在Bean定义中指定一个普通的初始化方法,然后在XML配置文件中通过指定

init-method属性来完成。

如下面的定义所示:

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {		
		public void init() {
			// do some initialization work
		}
	}

 ### 析构回调

1、实现org.springframework.beans.factory.DisposableBean接口的bean允许在容器销毁该bean的时候获得

一次回调。DisposableBean接口也只规定了一个方法:

void destroy() throws Exception;

2、通常,要避免使用DisposableBean标志接口而且不鼓励使用该接口,因为这样会将代码与Spring耦合在一

起。有一个可选的方案是,在bean定义中指定一个普通的析构方法,然后在XML配置文件中通过指定

destroy-method属性来完成。如下面的定义所示:

<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean {
		public void cleanup() {
			// do some destruction work (like releasing pooled connections)
		}
	}

 3、在Spring中有三种方式可以控制bean的生命周期行为: InitializingBean 和 DisposableBean 回调接口;

自定义init() 和 destroy() 方法; @PostConstruct 和@PreDestroy annotations.

4、在非web应用中优雅地关闭Spring IoC容器

AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(new String []{"beans.xml"});
    // add a shutdown hook for the above context... 
    ctx.registerShutdownHook();

相关推荐