Spring 从核心而言是一个DI(依懒注入)容器,其设计是一种无入侵性的高扩展框架,即无需代码中涉及Spring专有类,即可将其纳入Spring容易进行管理。org.springframework.beans包中包括了这些核心组件的实现类。核心中的核心为BeanWrapper和BeanFactory类,从技术角度来说这两个类并不复杂。
1、Bean Wrapper
这个BeanWrapper类很简单,提供了一套Bean的操作方法,如apache -BeanUtils一样。通过BeanWrapper,我们可以无需在编码时就指定JavaBean的实现类和属性值,通过在配置文件
加以设定,就可以在运行期动态创建对象并设定其属性(依赖关系)。 一个简单的例子:
public static void testBeanWrapper(){
try {
Object obj=Class.forName("com.spring.UpperAction").newInstance();
BeanWrapper bw=new BeanWrapperImpl(obj);
bw.setPropertyValue("message","peidw");
System.out.println(bw.getPropertyValue("message"));
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2、Bean Factory
BeanFactory负责根据配置配置文件创建Bean实例,可以配置的项目有:
1 、Bean属性值及依赖关系
2、Bean创建模式(是否单态模式)
3、Bean初始化及销毁
4、Bean的依赖关系
<beans>
<description>Spring Bean Configuration Sample</description>
<bean
id="TheAction" ⑴
class="net.xiaxin.spring.qs.UpperAction" ⑵
singleton="true" ⑶
init-method="init" ⑷
destroy-method="cleanup" ⑸
depends-on="ActionManager" ⑹
>
<property name="message">
<value>HeLLo</value> ⑺
</property>
<property name="desc">
<null/>
</property>
<property name="dataSource">
<ref local="dataSource"/> ⑻
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/sample</value>
</property>
</bean>
这是一个比较完整的Bean配置,id表示一个类在BeanFactory中的唯一标识
class 是java类名,singleton 为true表示使用单态,init-method初始化方法在BeanFactory创建Bean后执行的初始化方法。destroy-method销毁方法,在bean销毁时执行,一般用于资源释放。depends-on Bean的依懒关系。<value>节点用于指定一个属性值,ref节点用于引用另一个bean的属性。
联合上面关于BeanWrapper的内容,我们可以看到,BeanWrapper实现了针对单个Bean的属性设定操作。而BeanFactory则是针对多个Bean的管理容器,根据给定的配置文件,BeanFactory从中读取类名、属性名/值,然后通过Reflection机制进行Bean加载和属性设定。
3、ApplicationContext
BeanFactory提供了针对Java Bean的管理功能,而ApplicationContext提供了一个更为框架化的
实现(从上面的示例中可以看出,BeanFactory的使用方式更加类似一个API,而非Framework style)。
ApplicationContext覆盖了BeanFactory的所有功能,并提供了更多的特性。此外,
ApplicationContext为与现有应用框架相整合,提供了更为开放式的实现(如对于Web应用,我们可以在
web.xml中对ApplicationContext进行配置)。
相对BeanFactory而言,ApplicationContext提供了以下扩展功能:
1. 国际化支持
我们可以在Beans.xml文件中,对程序中的语言信息(如提示信息)进行定义,将程序中的提示
信息抽取到配置文件中加以定义,为我们进行应用的各语言版本转换提供了极大的灵活性。
2. 资源访问
支持对文件和URL的访问。
3. 事件传播
事件传播特性为系统中状态改变时的检测提供了良好支持。
4. 多实例加载
可以在同一个应用中加载多个Context实例。
一个国际化支持例子
public static void testLanguage(){
ApplicationContext ac=new FileSystemXmlApplicationContext("src/bean.xml");
Object[] arg=new Object[]{"kkui",Calendar.getInstance().getTime()};
//以系统默认的Locale加载信息(对winxp而言默认的是zh_CN)
String zhmsg=ac.getMessage("userinfo",arg, Locale.CHINA);
String usmsg=ac.getMessage("userinfo",arg, Locale.US);
System.out.println(zhmsg);
System.out.println(usmsg);
}
需要在beans.xml文件配置使用多资源
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
这里声明了一个名为messageSource的Bean(注意对于Message定义,Bean ID必须为
messageSource,这是目前Spring的编码规约),对应类为ResourceBundleMessageSource,
目前Spring中提供了两个MessageSource接口的实现,即
ResourceBundleMessageSource和ReloadableResourceBundleMessageSource,后
者提供了无需重启即可重新加载配置信息的特性。
资源文件message_zh.properties
userinfo=登陆用户:[{0}] 登陆时间[{1}]
国际化支持在实际开发中可能是最常用的特性。对于一个需要支持不同语言环境的应用而言,我们所采取的最常用的策略一般是通过一个独立的资源文件(如一个properties文件)完成所有语言信息(如界面上的提示信息)的配置,Spring对这种传统的方式进行了封装,并提供了更加强大的功能.
资源访问例子
Resource rs = ctx.getResource("classpath:config.properties");
File file = rs.getFile();
事件传播机制例子
ApplicationContext基于Observer模式(java.util包中有对应实现),提供了针对Bean的事件传播功能。通过Application. publishEvent方法,我们可以将事件通知系统内所有的ApplicationListener。下面是一个例子:
package com.spring;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
public class LoginAction implements ApplicationContextAware{
private ApplicationContext ac;
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
// TODO Auto-generated method stub
this.ac=arg0;
}
public int login(String username,String password){
ActionEvent ae=new ActionEvent(username);
this.ac.publishEvent(ae);
return 0;
}
}
package com.spring;
import org.springframework.context.ApplicationEvent;
public class ActionEvent extends ApplicationEvent {
public ActionEvent(Object source) {
super(source);
}
}
package com.spring;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class ActionListener implements ApplicationListener{
public void onApplicationEvent(ApplicationEvent event) {
if(event instanceof ActionEvent){
System.out.println(event.toString());
}
}
}
需要在beans.xml文件里添加以下配置
<bean id="loginaction" class="net.xiaxin.beans.LoginAction"/>
<bean id="listener" class="net.xiaxin.beans.ActionListener"/>
测试方法:
public static void testListener(){
ApplicationContext ac=new FileSystemXmlApplicationContext("src/bean.xml");
LoginAction la=(LoginAction)ac.getBean("loginaction");
la.login("peidw", "123456");
}
Struts in Spring
Struts和Spring是如何整合,为了在struts加加载Spring Context;在struts-config.xml文件中添加以下配置
<struts-config>
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml" />
</plug-in>
</struts-config>
通过plug-in我们实现了Spring Context的加载,不过仅仅加载Context并没有什么实际意义,我们还需要修改配置,将Struts Action交给Spring容器进行管理:
posted on 2006-11-25 20:30
有猫相伴的日子 阅读(1702)
评论(0) 编辑 收藏 所属分类:
spring