IOC之组件创建顺序
bean之间的依赖 depends-on 属性
默认情况下。bean对象创建的顺序,是从上到下 depends-on 可以设定依赖
bean对象:
public class A {
public A() {
System.out.println("A 被创建了");
}
}
public class B {
public B() {
System.out.println("B 被创建了");
}
}
public class C {
public C() {
System.out.println("C 被创建了");
}
}
配置文件:
<!-- 默认情况下。bean对象创建的顺序,是从上到下
depends-on 可以设定依赖
-->
<bean id="a" class="com.zy.pojo.A" depends-on="b,c"/>
<bean id="b" class="com.zy.pojo.B" />
<bean id="c" class="com.zy.pojo.C" />
测试:
基于xml配置文件的自动注入
public class Car {
private String carNo;
private String name;
public class Person {
private Car car;
public Person(Car car) {
this.car = car;
}
配置文件:
<bean id="car2" class="com.zy.pojo.Car">
<property name="name" value="奔驰"/>
<property name="carNo" value="京B2f453"/>
</bean>
<!--
autowire 属性设置是否自动查找bean对象并给子对象赋值
default 和 no 表示不自动查找并注入(你不赋值,它就null)
byName 是指通过属性名做为id来查找bean对象,并注入
1、找到就注入
2、找不到就为null
byType 是指按属性的类型进行查找并注入 使用的set注入
1、找到一个就注入
2、找到多个就报错
3、没有找到就为null
constructor 是指按构造器参数进行查找并注入。
1、先按照构造器参数类型进行查找并注入
2、如果按类型查找到多个,接着按参数名做为id继续查找并注入。
3、按id查找不到,就不赋值。
-->
<bean id="person" class="com.zy.pojo.Person" autowire="constructor">
<property name="name" value="person"/>
</bean>
测试:
Bean
Bean 定义
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的,例如,已经在先前章节看到的,在 XML 的表单中的 定义。
bean 定义包含称为配置元数据的信息,下述容器也需要知道配置元数据:
如何创建一个 bean
bean 的生命周期的详细信息
bean 的依赖关系
上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。
Bean的作用域
创建一个bean定义,其实质是用该bean定义对应的类来创建真正实例的“配方”。把bean定义看成一个配方很有意义,它与class很类似,只根据一张“处方”就可以创建多个实例。不仅可以控制注入到对象中的各种依赖和配置值,还可以控制该对象的作用域。这样可以灵活选择所建对象的作用域,而不必在Java Class级定义作用域。Spring Framework支持五种作用域,分别阐述如下表。
五种作用域中,request、session 和 global session 三种作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于 web 的 Spring ApplicationContext 环境。
1. singleton——唯一 bean 实例
当一个 bean 的作用域为 singleton,那么Spring IoC容器中只会存在一个共享的 bean 实例,并且所有对 bean 的请求,只要 id 与该 bean 定义相匹配,则只会返回bean的同一实例。 singleton 是单例类型(对应于单例模式),就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,但我们可以指定Bean节点的 lazy-init=”true”
来延迟初始化bean,这时候,只有在第一次获取bean时才会初始化bean,即第一次请求该bean时才初始化。 每次获取到的对象都是同一个对象。注意,singleton 作用域是Spring中的缺省作用域。要在XML中将 bean 定义成 singleton ,可以这样配置:
<bean id="ServiceImpl" class="com.zy.service.ServiceImpl" scope="singleton">
也可以通过 @Scope
注解(它可以显示指定bean的作用范围。)的方式
@Service
@Scope("singleton")
public class ServiceImpl{
}
2. prototype——每次请求都会创建一个新的 bean 实例
当一个bean的作用域为 prototype,表示一个 bean 定义对应多个对象实例。 prototype 作用域的 bean 会导致在每次对该 bean 请求(将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean() 方法**)时都会创建一个新的 bean 实例。prototype 是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的 bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域。** 在 XML 中将 bean 定义成 prototype ,可以这样配置:
<bean id="account" class="com.zy.DefaultAccount" scope="prototype"/>
或者
<bean id="account" class="com.zy.DefaultAccount" singleton="false"/>
通过 @Scope
注解的方式实现就不做演示了。
3. request——每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效
request只适用于Web程序,每一次 HTTP 请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束。 在 XML 中将 bean 定义成 request ,可以这样配置:
<bean id="loginAction" class=com.zy.LoginAction" scope="request"/>
4. session——每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效
session只适用于Web程序,session 作用域表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效.与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的 HTTP session 中根据 userPreferences 创建的实例,将不会看到这些特定于某个 HTTP session 的状态变化。当HTTP session最终被废弃的时候,在该HTTP session作用域内的bean也会被废弃掉。
<bean id="userPreferences" class="com.zy.UserPreferences" scope="session"/>
5. globalSession
global session 作用域类似于标准的 HTTP session 作用域,不过仅仅在基于 portlet 的 web 应用中才有意义。Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portle t所共享。在global session 作用域中定义的 bean 被限定于全局portlet Session的生命周期范围内。
<bean id="user" class="com.zy.Preferences "scope="globalSession"/>
Bean的生命周期
对于单例的bean,生命周期有11个步骤:
1.instantiate bean对象实例化,bean对象实例化,是在加载配置文件的时候实例的。即,我们启动spring容器的时候,加载配置文件,此时就实例化bean了。
2.populate properties 封装属性
3.如果Bean实现BeanNameAware, 执行 setBeanName