Spring框架的本质:通过XML配置来驱动Java代码,这样就可以把原本由Java代码管理的耦合关系,提取到XML配置文件中管理,这就实现了系统中各组件的解耦,有利于后期的升级和维护。
对于开发者来说,开发者使用Spring框架主要是做两件事(1)开发Bean(2)配置Bean。对于Spring来说,它要做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法完成依赖注入,
一、Bean的基本定义
<bean.../>是<beans.../>元素的子元素,<beans.../>元素可以包含多个<bean.../>子元素,每个<bean.../>子元素定义一个Bean,每个Bean对应Spring容器里的一个Java实例。
定义Bean时有两个实例:
id:确定该Bean的唯一标识,容器对bean的管理、访问,以及该Bean的依赖关系,都通过该属性来完成。Bean的id属性在Spring容器中应该是唯一的。
class:指定该bean的具体实现类,这里不能是接口。Spring容器必须知道Bean的实现类,而不能使接口。在通常情况下,Spring会直接使用new关键字创建搞Bean的实例,因此,这里必须提供Bean实现类的类名。
二、容器中Bean的作用域
当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域。
singleton:单例模式,在整个Spring IoC容器中,singleton作用域的Bean将只生成一个实例。
prototype:每次通过容器的getBean()方法获取prototype作用域的Bean时,将会产生一个新的Bean实例。
request:对于一次Http请求,request作用域的Bean将只生成一个实例,这意味着,在同一次的http请求中,程序每次请求该Bean,得到的总是同一个实例。只有在Web应用中使用spring时,作用域才会生效。
session:对于一次Http、会话,session作用域的Bean将只生成一个实例,这意味着在同一次Http会话内,程序每次请求该Bean,得到的总是同一个实例。只有在Web应用中使用Spring时,该作用域才真正生效。
global session:每个全局的http session对应一个Bean实例,在典型的情况下,仅在使用portlet context的时候才有效。只有在Web应用中使用Spring时,该作用域才真正生效。
比较常用的是singleton和prototype两种作用域,对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个bean被设置成prototype作用域,程序每次请求该id的Bean,Spring都会新建一个bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new关键字创建Bean实例,一旦创建成功,容器就不再跟踪实例,也不会维护Bean实例的状态。
如果不指定Bean的作用域,Spring默认使用singleton作用域。
三、常用注解
@Configuration:用于修饰一个java配置类
@Bean:用于修饰一个方法,将该方法的返回值定义成容器中的一个Bean
@Value:用于修饰一个Field,用于为该Field配置一个值,相当于配置一个变量。
使用了Java配置类来管理Spring容器中的Bean及其依赖关系,此时就采用以下方式来创建Spring容器:
//创建Spring容器
ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);
@import:修饰一个Java配置类,用于向当前Java配置类中导入其它配置类。
@scope:用于修饰一个方法,指定该方法对应的Bean的生命域。
@Lazy:用于修饰一个方法,指定该方法对应的Bean是否需要延迟初始化。
@DependsOn:用于修饰一个方法,指定在初始化该方法对应的Bean之前初始化指定的Bean。
在实际项目中,可能会混合使用XML配置和Java类配置
(1)如果以XML配置为主,就需要让XML配置能加载Java类配置,只要在XML配置中增加如下代码即可:
<context:annotation-config/>
<!---加载Java配置类-->
<bean class="......"/>
由于以XML配置文件为主,因此应用创建Spring容器时,还是以这份XML配置文件为参数来创建ApplicationContext对象。那么Spring会先加载这份XML配置文件,再根据这份XML配置文件的指示去加载指定的Java配置类
(2)如果以Java类配置为主,就需要让Java配置类能加载XML配置。这就需要借助于@ImportResource注解,这个注解可修饰Java配置类,用于导入指定的XML配置文件。也就是在Java配置类上增加如下注解:
@configuration
//导入XML配置
@ImportResource("classpath:/beans.xml")
public class MyConfig{
...
}
由于以Java类配置为主,因此应用创建Spring容器时,应以Java配置类为参数,通过创建AnnotationConfigApplicationContext对象作为Spring容器。那么Spring容器会先加载这个Java配置类,再根据这个Java配置类的指示去加载指定的XML配置文件。