3.3.1 延迟初始化bean
使用时才加载:配置文件用 lazy-init="true" 进行配置
<bean id="helloApi" class="cn.javass.spring.chapter2.helloworld.HelloImpl" lazy-init="true"/>
3.3.2 depends-on:指定了bean的初始化销毁的顺序
<bean id="resourceBean" class="test.spring.DI.chapter3.c3.ResourceBean" init-method="init" destroy-method="destroy">
<property name="file" value="D:/test.txt"/>
</bean>
<bean id="dependentBean" class="test.spring.DI.chapter3.c3.DependentBean" init-method="init" destroy-method="destroy" depends-on="resourceBean">
<property name="resourceBean" ref="resourceBean"/>
</bean>
在上述的配置文件中,DependentBean指定了depends-on="resourceBean",所以初始时会先初始化resourceBean的init方法,后执行DependentBean的init(),最后调用resourceBean destroy()销毁,看下面一段代码的实例:
ResourceBean :
public class ResourceBean {
private FileOutputStreamfos;
private Filefile;
//初始化方法
public void init() {
System.out.println("ResourceBean:========初始化");
//加载资源,在此只是演示
System.out.println("ResourceBean:========加载资源,执行一些预操作");
try {
this.fos =new FileOutputStream(file);
}catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//销毁资源方法
public void destroy() {
System.out.println("ResourceBean:========销毁");
//释放资源
System.out.println("ResourceBean:========释放资源,执行一些清理操作");
try {
fos.close();
}catch (IOException e) {
e.printStackTrace();
}
}
public FileOutputStreamgetFos() {
return fos;
}
public void setFile(File file) {
this.file = file;
}
}
DependentBean:
public class DependentBean {
ResourceBeanresourceBean;
public void write(String ss)throws IOException {
System.out.println("DependentBean:=======写资源");
resourceBean.getFos().write(ss.getBytes());
}
//初始化方法
public void init()throws IOException {
System.out.println("DependentBean:=======初始化");
resourceBean.getFos().write("DependentBean:=======初始化=====".getBytes());
}
//销毁方法
public void destroy()throws IOException {
System.out.println("DependentBean:=======销毁");
//在销毁之前需要往文件中写销毁内容
resourceBean.getFos().write("DependentBean:=======销毁=====".getBytes());
}
public void setResourceBean(ResourceBean resourceBean) {
this.resourceBean = resourceBean;
}
}
测试类:
@Test
public void test(){
ClassPathXmlApplicationContext cx =new ClassPathXmlApplicationContext("com/comverse/timesheet/config/dispatcher-servlet.xml");
cx.registerShutdownHook();
DependentBean bean = cx.getBean("dependentBean",DependentBean.class);
try {
bean.write("22222");
}catch (IOException e) {
e.printStackTrace();
}
}
3.3 自动装配
spring支持几种方式的自动装配: no byName byType constructor
no:不支持自动装配,必须明确指定依赖
byName:根据name进行装配,只用通过setter进行注入,比如我们有方法“setHelloApi”,则“byName”方式Spring容器将查找名字为helloApi的Bean并注入,如果找不到指定的Bean,将什么也不注入。
<bean id="helloApi" class="test.spring.DI.chapter3.c1.HelloServiceImpl1"/>
<bean id="bean" class="test.spring.DI.chapter3.c3.HelloApiDecorator" autowire="byName"/>
HelloApiDecorator类:
public class HelloApiDecorator implements HelloApi{
private HelloApihelloApi;
private Stringmessage;
public HelloApiDecorator() {
}
public void setMessage(String message) {
this.message = message;
}
public HelloApiDecorator(HelloApi helloApi) {
this.helloApi = helloApi;
}
public void setHelloApi(HelloApi helloApi) {
this.helloApi = helloApi;
}
@Override
public void sayHello() {
System.out.println("==========装饰开始===========");
helloApi.sayHello();
System.out.println("==========装饰完毕===========");
}
}
测试:
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("com/comverse/timesheet/config/dispatcher-servlet.xml");
HelloApi helloApi = context.getBean("bean", HelloApi.class);
helloApi.sayHello();
byName方式进行自动装配,HelloApiDecorator类中必须提供HelloApi的setter方法进行装配
byType:根据type类型进行注入,基于setter进行注入,比如说setHelloApi 方法需要注入HelloApi 类型数据,spring容器会先在查找HelloApi的类型数据,如果找到则注入一个bean,如果有多个,则优先注入primary="true",否则抛出异常表明有多个不知道要注入哪个bean
配置方式与byName 注入配置的方式一致,将注入类型更改成byType就可以
constructor: 将注入类型更改为autowire="constructor",基于构造器注入
web应用中作用域:
request:表示每个请求需要容器创建一个全新Bean。比如提交表单的数据必须是对每次请求新建一个Bean来保持这些表单数据,请求结束释放这些数据
session作用域:表示每个会话需要容器创建一个全新Bean。比如对于每个用户一般会有一个会话,该用户的用户信息需要存储到会话中,此时可以将该Bean配置为web作用域
globalSession:类似于session作用域,只是其用于portlet环境的web应用。如果在非portlet环境将视为session作用域
网友评论