之前一直都是用jsp+servlet+javabeans搭建网站应用,遂总结下今天学习的spring框架的内容
相应的jar包:http://download.youkuaiyun.com/detail/fengsigaoju/9835903
为了统一,在src下建立一个包命名为spring.firstdemo
我们首先假设一个卖票的场景,有一个实体类ticket,其有3个属性,起点终点和票价。
package spring.firstdemo;
public class ticket {
private double value;//价格
private String start;//起点
private String end;//终点
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
public void PrintInformation() {
System.out.println("从"+start+"开往"+end+"的票价为:"+value);
}
public static void main(String[] args) {
ticket t=new ticket();
t.setStart("南京");
t.setEnd("上海");
t.setValue(89.5);
t.PrintInformation();
}
}
输出信息:
从南京开往上海的票价为:89.5
我们采用spring框架的依赖注入来实现相同的效果:
设值注入
首先在src新建一个名为beans.xml的文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="t" class="spring.firstdemo.ticket">
<property name="start" value="南京"/>
<property name="end" value="上海"/>
<property name="value" value="89.5"/>
</bean>
</beans>
同时新建一个测试类test_first:
package spring.firstdemo;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class test_first {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("first_beans.xml"));
ticket t= (ticket)factory.getBean("t");//使用spring控制反转创建对象
t.PrintInformation();
factory.destroySingletons();
}
}
也能起到同样的效果,我们分析下xml配置文件,这里整个bean类就是一个ticket实例,对于每一个实例赋值时 name就是变量名,value就是值,注意如果删去相应的set类,那么spring将无法正常对这些数据初始化。也就是说采用配置注入需要在需要实例化的类中创建相应的set方法(eclipse中可以右击后点击source自动加载)
传入数值参数比较好理解,那么如果传入的是类呢。
我们再假设一个车站类station,该车站仅卖一种票。
修改xml文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="t" class="spring.firstdemo.ticket">
<property name="start" value="南京"/>
<property name="end" value="上海"/>
<property name="value" value="89.5"/>
</bean>
<bean id="s" class="spring.firstdemo.station">
<property name="tick" ref="t"/>
</bean>
</beans>
新建station及其测试类:
package spring.firstdemo;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class station {
private ticket tick;
public ticket getTick() {
return tick;
}
public void setTick(ticket tick) {
this.tick = tick;
}
public void print(){
System.out.println("station已经加载");
}
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("first_beans.xml"));
station s= (station)factory.getBean("s");//使用spring控制反转创建对象
s.print();
factory.destroySingletons();
}
}
可以观察到station是采用ref传入参数ticket的,注意xml里的顺序不影响程序,也就是两者可以颠倒,同样需要注意配置注入需要保留set方法的参数。
运行结果为:
station已经加载
但是正常车站明显并不会只卖一种车票,所以我们需要用一个list存储所有的车票信息.
再次修改配置信息:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="t" class="spring.firstdemo.ticket">
<property name="start" value="南京"/>
<property name="end" value="上海"/>
<property name="value" value="89.5"/>
</bean>
<bean id="t2" class="spring.firstdemo.ticket">
<property name="start" value="南京"/>
<property name="end" value="北京"/>
<property name="value" value="200.1"/>
</bean>
<bean id="t3" class="spring.firstdemo.ticket">
<property name="start" value="杭州"/>
<property name="end" value="成都"/>
<property name="value" value="115.2"/>
</bean>
<bean id="station" class="spring.firstdemo.true_station">
<property name="list">
<list>
<ref bean="t"/>
<ref bean="t2"/>
<ref bean="t3"/>
</list>
</property>
</bean>
<bean id="s" class="spring.firstdemo.station">
<property name="tick" ref="t"/>
</bean>
</beans>
创建真车站true_station类:
package spring.firstdemo;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class true_station {
private List<ticket>list=new ArrayList<ticket>();
public List<ticket> getList() {
return list;
}
public void setList(List<ticket> list) {
this.list = list;
}
public void print(){//打印当前拥有的车票
for (ticket t:list){
t.PrintInformation();//打印每一张车票的信息
}
}
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("first_beans.xml"));
true_station true_station= (true_station)factory.getBean("station");//使用spring控制反转创建对象
true_station.print();
factory.destroySingletons();
}
}
输出结果为:
从南京开往上海的票价为:89.5
从南京开往北京的票价为:200.1
从杭州开往成都的票价为:115.2
构造注入
如果说设值注入需要保留属性相应的set方法,那么构造注入需要保留相应的构造函数,这里以第三个station类为例子。
新建一个配置文件second_beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="t" class="spring.firstdemo.ticket">
<property name="start" value="南京"/>
<property name="end" value="上海"/>
<property name="value" value="89.5"/>
</bean>
<bean id="station" class="spring.firstdemo.station_second">
<constructor-arg index="0" ref="t"/>
</bean>
</beans>
新建station_second类:
package spring.firstdemo;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class station_second {
private ticket tick;
public station_second(ticket tick){//需要保留构造函数
this.tick=tick;
}
public void print(){
System.out.println("station已经加载");
}
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("second_beans.xml"));
station_second s= (station_second)factory.getBean("station");//使用spring控制反转创建对象
s.print();
factory.destroySingletons();
}
}
两者的选择:
1,如果依赖关系非常复杂,考虑到构造注入需要保留构造函数,那么构造函数里的内容会比较复杂,所以此时采用设值注入比较简洁。
2,如果使用没写第三方库,可能要求组建必须提供一个默认的构造函数,此时构造注入类型的依赖注入机制就存在局限性。
3,构造方法由于不存在set方法,不用担心上层代码在调用过程中执行set方法对组件产生印象。
总结:绝大情况下忽略二者的区别,哪个用的爽用哪个..