Spring环境搭建及简单demo

环境搭建

首先需要下载Spring框架 

此外,还需要下载一个必要组件 commons-logging      

简单demo及控制反转(IOC)和依赖注入(DI)简介

J2EE提倡面向接口编程,Spring也是针对的接口编程,即在代码中只使用规范(即接口),而将真正的实现类配置在文件中,由Spring的配置文件来决定将会使用哪一个实现类,这也叫做控制反转(IOC)或者依赖注入(DI)。

现在我们假设有这么一个场景, 我们指定一类人去使用一类斧头,不同的人可以使用不同的斧头,当然其效果不一样。

按照J2EE的建议,首先我们需要定义“人”和“斧头”两个规范,即创建两个接口,

斧头接口,

1 package spi;
2 
3 public interface Axe {
4     public String chop();
5 }

斧头接口的一个实现,

复制代码
1 package spi;
2 
3 public class StoneAxe implements Axe { 
4     public String chop() {
5         return "石斧砍柴好慢";
6     }
7 }
复制代码

人接口

1 package spi;
2 
3 public interface Person {
4     public void useAxe();
5 }

人接口的一个实现,

复制代码
 1 package spi;
 2 
 3 public class Chinese implements Person {
 4     private Axe axe;
 5     public void setAxe(Axe axe) {
 6         this.axe = axe;
 7     }
 8     public void useAxe() {
 9         System.out.println("我打算去砍点柴火");
10         System.out.println(axe.chop());
11     }
12 }
复制代码

下面要写一个测试类,使用Person接口的一个实现类的对象,去调用Axe的一个实现类的对象,

按照传统编程方式,我们一般会写成下面这样,

复制代码
 1 package spi;
 2 
 3 public class BeanTest {
 4     public static void main(String[] args) {
 5         Chinese p = new Chinese();
 6         StoneAxe axe = new StoneAxe();
 7         p.setAxe(axe);
 8         p.useAxe();
 9     }
10 }
复制代码

 

 重点是第6行和第7行,即Chinese类和StoneAxe类耦合在了java代码中,如果现在需求有变,我们在这里要使用一种新的斧头,即Axe有一个新的实现类SteelAxe,那么就必须修改这里的代码, SteelAxe axe = new SteelAxe(); 这对于代码维护其实并不方便。 对于这个问题,Spring的解决方案是将上面的步骤放在配置文件中,具体实现方法是这样的,

首先创建一个配置文件,名字自定义即可,

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xsi:schemaLocation="http://www.springframework.org/schema/beans
 5         http://www.springframework.org/schema/beans/spring-beans.xsd">
 6     <bean id="chinese" class="spi.Chinese">
 7         <property name="axe" ref="stoneAxe" />
 8     </bean>
 9     <bean id="stoneAxe" class="spi.StoneAxe" />
10     <bean id="win" class="javax.swing.JFrame" />
11     <bean id="date" class="java.util.Date" />
12 </beans>
复制代码

可以看到配置文件中定义了上面两个接口的实现类的具体包路径,其中stoneAxe还被定义成了Chinese类的一个属性,

有了这个配置文件之后,Spring就可以在底层利用java反射,首先创建出两个类对象(Chinese和StoneAxe),接着马上执行对象的setter方法,依据配置文件中各个类的依赖关系去初始化每个对象的属性,而这个过程,正是上面传统编程中的StoneAxe axe = new StoneAxe();p.setAxe(axe);这两部!

下面看看Spring方式在测试代码中的写法,

复制代码
 1 package spi;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 public class BeanTest {
 7     public static void main(String[] args) {
 8         ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
 9         Person p = ctx.getBean("chinese", Person.class);
10         p.useAxe();
11     }
12 }
复制代码

执行结果,

1 我打算去砍点柴火
2 石斧砍柴好慢

 

可以看到,在测试代码中,完全没有了Chinese和StoneAxe两个类的耦合依赖关系,转而将依赖关系放在了上面的XML文件中,底层通过java反射的方式进行初始化。

即,将java代码中对象间的依赖关系的控制权交给了Spring配置文件,由Spring来生成对象,并且设置对象间的依赖关系,这就是控制反转(IOC)或者叫依赖注入(DI)。

Spring自动生成对象(可禁用)和设置依赖关系是最基本的功能。

Spring的IOC(或DI)机制,极大地降低了组件间的耦合,例如对于上面的需求变更,我们只需要在XML文件中新增一个bean节点,并设置好依赖关系即可,而测试代码不需要任何改变!

新增Axe的实现类,

复制代码
1 package spi;
2 
3 public class SteelAxe implements Axe { 
4     public String chop() {
5         return "钢斧砍柴好快";
6     }
7 }
复制代码

修改Spring配置文件,

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xsi:schemaLocation="http://www.springframework.org/schema/beans
 5         http://www.springframework.org/schema/beans/spring-beans.xsd">
 6     <bean id="chinese" class="spi.Chinese">
 7         <property name="axe" ref="steelAxe" />
 8     </bean>
 9     <bean id="stoneAxe" class="spi.StoneAxe" />
10     <bean id="steelAxe" class="spi.SteelAxe" />
11     <bean id="win" class="javax.swing.JFrame" />
12     <bean id="date" class="java.util.Date" />
13 </beans>
复制代码

执行测试类结果,

1 我打算去砍点柴火
2 钢斧砍柴好快

5.设值注入和构造注入

对于依赖注入,有两种方式,一种是设置注入,即上面XML配置文件中设置<property />标签的方式,这种方法本质上是利用反射调用对象的setter方式进行初始化。

另外,还可以使用构造注入的方式,即在XML配置文件中使用<constructor-arg />标签,不过这种方式要求有对应的构造方法才行。

对于上面的例子,首先我们要让Chinese类有一个构造方法,

1     public Chinese(Axe axe) {
2         this.axe = axe;
3     }

接着我们将XML配置文件中的<peroperty>标签用<constructor-arg>标签替换,

1     <bean id="chinese" class="spi.Chinese">
2         <!--  <property name="axe" ref="stoneAxe" /> -->
3         <constructor-arg ref="stoneAxe" />
4     </bean>

 

我们将得到一样的结果,只是实现的方式不一样而已。对于设值注入和构造注入两种方式如何选择呢,

一般的,如果对依赖关系无需变化地注入,尽量采用构造注入。其他依赖关系的注入则考虑采用设值方式注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值