今天主要通过简单配置xml文档、编写底层java代码并通过Spring将二者进行连接的思想实现了一个很小的Spring基础代码,旨在了解基本的实现机理。
代码主要包括:
Action接口:
Action 接口定义了一个execute 方法,不同的Action 实现提供了各自的execute方法,以完成目标逻辑。
public interface Action {
public String execute(String str);
}
Action接口的两个实现UpperAction、LowerAction
(UpperAction将其message属性与输入字符串相连接,并返回其大写形式。
LowerAction将其message属性与输入字符串相连接,并返回其小写形式。)
public class UpperAction implements Action {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String string) {
message = string;
}
public String execute(String str) {
return (getMessage() + str).toUpperCase();
}
}
Spring配置文件(bean.xml)
注:bean.xml配置文件应该与.project工程在同一目录下
< beans >
< description >Spring Quick Start </ description >
< bean id ="TheAction"
class ="net.xiaxin.spring.qs.UpperAction" >
< property name ="message" >
< value >HeLLo </ value >
</ property >
</ bean >
</ beans >
测试代码
利用Spring组件实现简单的IOC思想
public void testQuickStart() {
ApplicationContext ctx= new
FileSystemXmlApplicationContext( "bean.xml");
Action action = (Action) ctx.getBean( "TheAction");
System.out.println(action.execute( "Rod Johnson"));
}
基础代码&Spring组件&XML文件之间的关系
根据我画的图可以看出:
1. 我们的所有程序代码中(除测试代码之外),并没有出现Spring中的任何组件。
2. UpperAction和LowerAction的Message属性均由Spring通过读取配置文件(bean.xml)动
态设置。
3. 客户代码(这里就是我们的测试代码)仅仅面向接口编程,而无需知道实现类的具体名称。同时,
我们可以很简单的通过修改配置文件来切换具体的底层实现类。
而这些又对实际开发有和帮助呢
? 首先,我们的组件并不需要实现框架指定的接口,因此可以轻松的将组件从Spring中脱离,甚
至不需要任何修改(这在基于EJB框架实现的应用中是难以想象的)。
? 其次,组件间的依赖关系减少,极大改善了代码的可重用性。
Spring的依赖注入(DI)机制,可以在运行期为组件配置所需资源,而无需在编写组件代码时就加以指定,从而在相当程度上降低了组件之间的耦合
从这个例子看到,通过Spring组件,在运行期间将字符串“HeLLo”注入到Action实现类的Message属性中。
IoC,看了很多的Spring书籍,都说IoC是Spring的核心思想,所以想好好理解一下,按我理解的来看,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
依赖注入(Dependency Injection)是IoC的另一种称呼,可能这种称呼感觉起来会更加精准一些,亦即组件之间的依赖关系由容器在运行期间决定,
因此我认为依赖注入的目标并非是为web开发带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活\可扩展的平台所作出的贡献,同时依赖注入机制意味着,组件得到重用的机会将会更多。(代码共享主义社会的实现将不远亦)
Spring的几个重要类及相应接口
BeanFactory
Bean Factory负责根据配置文件创建Bean实例,可以配置的项目有:
1. Bean属性值及依赖关系(对其他Bean的引用)
2. Bean创建模式(是否Singleton模式,即是否只针对指定类维持全局唯一的实例)
3. Bean初始化和销毁方法
4. Bean的依赖关系
ApplicationContext
ApplicationContext覆盖了BeanFactory的所有功能,并提供了更多的特性,所以一般开发都会使用ApplicationContext
构造ApplicationContext的两种种方法:
application context构造器通常使用字符串或字符串数组作为资源(比如组成context定义 的XML文件)的定位路径。
当这样的定位路径没有前缀时,指定的 Resource 类型会通过这个路径来被创建并被用来载入bean的定义,这都取决于你所指定的application context。
1、如果使用下面的代码来创建ClassPathXmlApplicationContext :
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
――这个xml文件中的bean的定义会通过classpath载入并使用ClassPathResource。
2、利用FileSystemXmlApplicationContext
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
这种定义中,xml文件中的bean的定义会通过文件系统从相对于当前工作目录中被载入。
注意1:
请注意如果定位路径使用classpath前缀或标准的URL前缀,那它就会覆盖默认的Resource 类型。因此下面的FileSystemXmlApplicationContext...
ApplicationContext ctx =
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
实际上会通过classpath载入其bean定义。然而他仍是个FileSystemXmlApplicationContext。如果后面它被当作ResourceLoader 来使用,那么任何没有使用前缀的路径依然会被当作一个文件系统路径。
注意2:
实际上如果的确需要使用绝对路径,那你最好就不要使用 FileSystemResource 或 FileSystemXmlApplicationContext来确定绝对路径。我们可以通过使用 file: URL前缀来强制
使用UrlResource。
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:/some/resource/path/myTemplate.txt");
// 强迫FileSystemXmlApplicationContext 来加载通过UrlResource定义的文件
ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:/conf/context.xml");
(明天继续explorer...)
明日安排:
继续熟悉ApplicationContext
WebContext
Web 应用与MVC