未知数据

简,是一种境界.

首页 新随笔 联系 聚合 管理
  8 Posts :: 0 Stories :: 2 Comments :: 0 Trackbacks
第三章:Ioc容器
3.2.1 容器的概念
Spring容器提供的功能主要包括
1.组件的生命周期管理
2.组件的配置和组装服务
3.AOP支持
4.建立在AOP之上的声明式事物服务
3.2.2 IoC的概念
IoC inversion of Control 控制反转
public class BookService {
private BookDao bookDao = new DbBookDao();
public List<Book> listBooksByAuthor(String author) {
List<Book> books = bookDao.listAll();
Iterator<Book> it = books.iterator();
while(it.hasNext()) {
if(!it.next().getAuthor().equals(author)) {
it.remove();
}
}
return books;
}
}
如果系统中有很多组件,其生命周期和相互之间的依赖关系如果由组件自己来维护,不但大大增加了系统的复杂程度,而且导致组件组件很紧的耦合,继而给测试和维护带来很大困难.
在Ioc模式下,控制权发生了反转.组件不再由应用程序来创建和配置,而是由Ioc容器来负责,应用程序只是直接使用已经创建和配置好的组件.
public class BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao){
this.bookDao=bookDao;
}
public List<Book> listBooksByAuthor(String author) {
List<Book> books = bookDao.listAll();
Iterator<Book> it = books.iterator();
while(it.hasNext()) {
if(!it.next().getAuthor().equals(author)) {
it.remove();
}
}
return books;
上面没有创建组件bookDao的代码,只有使用组件.从而实现了组件的配置和使用的分离,并由Ioc容器负责管理组件的生命周期.

3.2.3 依赖注入的方式
为了让组件能在IoC容器中被装配出来,需要某种注入机制,Ioc使用"注入"机制将一种组件注入到另一种组件中.
Type1:接口注入
Type2:设置属性注入
Type3:构造方法注入
3.3 Spring提供的IoC容器
1.高扩展性无侵入式的框架
2.支持两种依赖注入方式:设置属性注入和构造方法注入.
3.提供两种不同的容器:BeanFactory和ApplicationContext
3.3.1 BeanFactory
应用程序将Bean的创建和配置全部委托给BeanFactory,然后从BeanFactory获取Bean并使用Bean.流程如下:
启动应用程序-->实例化BeanFactory-->从BeanFactory中获取Bean-->使用Bean-->销毁BeanFactory-->应用程序结束

org.springframework.beans.factory.BeanFactory的具体实现:
XmlBeanFactory 通过一个xml文件创建和配置Bean
从本地文件中载入:
InputStream is = new FileInputStream("beans.xml");
XmlBeanFactory factory = newXmlBeanFactory(is);
或者使用ClassPath定位:
ClassPathResource res = new ClassPathResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
3.3.2 使用ApplicationContext
从BeanFactory继承而来,所以本质仍然是一个BeanFactory.与基本的BeanFactory相比,还提供了国际化支持,事件的发布和通知机制等
3.4 bean初始化
基本的BeanFactory初始化和ApplicationContext初始化不同:
基本的BeanFactory在调用getBean("beanid")的时候才会创建这个bean
ApplicationContext则在自身初始化的时候创建了所有bean
因为ApplicationContext的特性,ApplicationContext是最佳选择.在启动的时候,可以检测配置文件出错.这比使用基本的BeanFactory在运行一段时间以后调用getBean()抛出异常要好得多.并且,演示加载会带来性能上的损失.ApplicationContext唯一的缺点是,由于要在启动的时候一次性创建所有bean.当定义的bean很多时,启动的时间比较长.
3.5 装配bean
装配Bean的方式就是在xml配置文件中对每个<bean>节点进行配置.
______________________________________________________________________________
public class ExampleBean {
private List list;
private int size = 100;
private String version;
private BasicBean basicBean;

public void setSize(int size) {
this.size=size;
}
public void setVersion(String version) {
this.version = version;
}
public void setBean(BasicBean basicBean) {
this.basicBean = basicBean;
}
public void init() {
list = new ArrayList(size);
}
}
<bean id="exampleBean" class="example.chapter3.ExampleBean" init-method="init">
<property name="size" value="10" />
<property name="version" value="1.0" />
<property name="bean" ref="basicBean" />
<property name="bean" <null /></property>
</bean>
1.init-method指定一个无参数的初始化方法
2.基本类型的注入,Spring会自动将value的值转化为合适的类型.若无法完成,则抛出异常.
3.如果注入的属性不是基本类型,而是引用类型,则用<ref>代替<value>.
4.如果对某个属性注入null,则必须使用<null/>
_________________________________________________________________________________________
public class ListBean {
public void setChildren(List children){}//普通list
public void setPrices(List<Float> prices) {}//泛型list
public void setFi(int[] fi) {}//int数组
}
<bean id="listBean" class="example.chapter3.ListBean">
<property name="children">
<list>
<value>A String</value>
<ref bean="basicBean" />
</list>
</property>
<property name="prices">
<list>
<value>1.24</value>
<value>2.24</value>
<value>3.24</value>
</list>
</property>
<property name="fi">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
</list>
</property>
</bean>
1.设置list和数组的方法是在<list>和</list>之间包含若干<value>或<ref>节点,可以混合使用<value>和<ref>
2.使用java5的泛型,Spring2.0可以强制将<value>的值转化为Float类型
3.set类型的注入和普通list相同,但set中不包含重复元素.
4.map的注入,每一项都是由一个键值和对应的值组成.例如:
public class MapBean {
public void setWeekday(Map map) {}
}
<bean id="mapBean" class="example.chapter3.MapBean">
<property name="weekday">
<map>
<entry key="Monday">
<value>one</value>
</entry>
<entry key="Tuesday">
<ref bean="listBean" />
</entry>
</map>
</property>
</bean>
key也可以是任意的Object.
<bean id="mapBean" class="example.chapter3.MapBean">
<property name="weekday">
<map>
<entry>
<key><ref bean="basicBean"></key>
<value>basic</value>
</entry>
<entry>
<key><ref bean="basicBean"></key>
<ref bean="setBean" />
</entry>

<!--
可简写成
<entry key-ref="basicBean" value="basic" />
<entry key-ref="listBean" value-ref="setBean" />
-->
</map>
</property>
</bean>

3.6 构造方法注入
public class ConstructorBean {
public ConstructorBean(int min,int max) {
System.out.println("(int,int)");
}
public ConstructorBean(String min,String max) {
System.out.println("(String,String)");
}
}
<bean id="constructorBean" class="example.chapter3.ConstructorBean">
<constructor-arg type="int" value="100">
<constructor-arg type="int" value="200">
</bean>
1.使用type属性指定构造方法的参数类型
2.推荐优先考虑设置属性方法注入
3.7 bean的作用域
<bean id="beanid" class="class" scope="">
spring2.0中一共定义了5中作用域:singleton,prototype,request,session,application.
1.singleton
如果不指定scope,默认值为singleton.Spring的IoC容器仅为每个bean创建一个实例,并保持Bean的引用.也就是说每次调用getBean()方法请求某一bean 时,Spring总返回相同的Bean实例
2.prototype
每次都返回一个新创建的bean实例.因此,Spring容器一旦将实例交给客户端,就不再对其跟踪引用,所以不能对prototype作用域的Bean定义destroy-method.

public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
System.out.println("Get date: "+context.getBean("date"));
Thread.sleep(1000);
System.out.println("Get date: "+context.getBean("date"));
Thread.sleep(1000);
System.out.println("Get date: "+context.getBean("date"));
Thread.sleep(1000);
}

<bean id="date" class="java.util.Date" scope="prototype" />

打印出的时间是不同的,说明返回3个不同的date对象实例,如果去掉scope,则每次打印出的时间都是一样的.


posted on 2008-02-25 14:33 未知数据 阅读(333) 评论(0)  编辑  收藏 所属分类: Spring

只有注册用户登录后才能发表评论。


网站导航: