Spring入门,HelloWorld
学习来源: http://www.yiibai.com/spring/spring-3-hello-world-example.html
http://outofmemory.cn/java/spring/spring-DI-via-setter-property-method
http://blog.csdn.net/loster_li/article/details/52863664
http://blog.csdn.net/yuebinghaoyuan/article/details/7337359
1. Spring bean:HelloWorld.java
Spring容器负责创建并管理所有的Java对象,在Spring中称这些Java对象为Bean。
Java文件和String配置文件中的Bean,他们的关系就像类和对象的关系。一个Java实体类可以在配置文件中有多个Bean。
package com.yiibai.core; /** * Spring bean * */ public class HelloWorld { private String name; public void setName(String name) { this.name = name; } public void printHello() { System.out.println("Spring 3 : Hello ! " + name); } }
2. Spring配置文件:applicationContext.xml
该文件用以声明所有可用的bean。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloBean" class="com.yiibai.core.HelloWorld"> <property name="name" value="Yiibai" />
<!-- 这里使用的依赖注入方式是“setter方法注入”,对于简单类型可用像这样直接使用value来设置,对于复杂的类型,则可用使用ref引用已经定义好的bean --> </bean> </beans>
3. 测试
package com.yiibai.core; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloBean"); obj.printHello(); } }
/**
* 执行结果: Spring 3 : Hello ! Yiibai
*/
二、由此对Spring相关概念的理解
1. 依赖注入(DI)
依赖注入方式有三种:setter方法注入(简单,用的多);构造方法注入;接口注入
1.1 setter方法注入
如上面的例子所示,在使用applicationContext.xml配置文件对可用bean进行声明的同时,向配置文件中注入属性(property节点)。
通过property节点下的name和value节点,在其所对应的bean中查找名为“name节点值”的属性的set()方法,将value赋值给该属性。
1.1.1 当bean的某属性较复杂时,可使用ref替代value。
package com.yiibai.core; /** * Spring bean * */ public class HelloWorld { private String name;
private ContactInfo contact; public ContactInfo getContact() { return contact; } public void setContact(ContactInfo contact) { this.contact = contact; } public void setName(String name) { this.name = name; } public void printHello() { System.out.println("Spring 3 : Hello ! " + name); } }
该bean中多出一个属性 private ContactInfo contact,其中Contact也是一个bean。
package com.yiibai.core; public class ContactInfo { private String address; private String zip; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getZip() { return zip; } public void setZip(String zip) { this.zip = zip; } }
显然,此时再尝试用value对该属性进行注入是不好搞的。这个时候就可以使用ref来代替value了(另外还有一种方法可以解决这种复杂的属性)。
在配置文件中添加ContactInfo的声明,并给他一个ID,用来被其他bean的ref引用。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="cn.outofmemory.ContactInfo" id="concat"> <property name="address" value="Street 5th" /> <property name="zip" value="9999" /> </bean> <bean class="cn.outofmemory.spring.Person"> <property name="name" value="John" /> <property name="age" value="20" /> <property name="contact" ref="concat" /> </bean> </beans>
还可以通过在bean中内置bean的方式对复杂结构的属性进行注入:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="cn.outofmemory.spring.Person"> <property name="name" value="John"/> <property name="age" value="20"/> <property name="contact"> <bean class="cn.outofmemory.ContactInfo"> <property name="address" value="Street 5th"/> <property name="zip" value="9999"/> </bean> </property> </bean> </beans>
1.2 构造方法注入
简单地讲,上面的setter方法注入是针对bean的每个属性进行注入(bean本身用的可能是默认的构造方法)。
而构造方法注入,则会给bean一个全参的构造方法。
//构造方法注入和setter方法注入的区别一:bean的构造方法
public class HelloWorld { public HelloWorld(String name){ this.name=name; }
//下面没有变化 private String name; public void setName(String name) { this.name = name; } public void printHello() { System.out.println("Spring 3 : Hello ! " + name); } }
<!-- 构造方法注入和setter方法注入的区别二:配置文件的节点不同 --> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="id" class="com.yiibai.core.HelloWorld"> <constructor-arg index="0" value="456"></constructor-arg> <!-- 这里使用下标索引来确定属性,而非属性名。当有更多属性时,再添加constructor-arg节点即可。 --> </bean> </beans>
property属性:<property name="id" value="123"></property>(其中name的值为原类中的属性名)
constructor-arg属性:<constructor-arg index="0" value="456"></constructor-arg>(其中index的值为0~n-1,n代表构造函数中的输入参数的数量)
1.3 接口注入
暂时没看懂: http://ghl116.iteye.com/blog/1474250
2. 控制反转(IOC)
IOC:inverse of Control:控制反转。意思是程序中的之间的关系,不用代码控制,而完全是由容器来控制。在运行阶段,容器会根据配置信息直接把他们的关系注入到组件中。同样,这也是依赖注入的含义。依赖注入和控制反转其实是一个概念。只不过强调的不同而已,依赖注入强调关系的注入是由容器在运行时完成,而控制反转强调关系是由容器控制。其实本质是一样的。
以学生、学校为例来讲,学生类中有学校这个属性,而学校也以类的形式存在:
package ioc.iocsample; /** * 学校类 * @author lhy * */ public class School { private String name; public School(String name) { this.name=name; } public void printInfo() { System.out.println("该学校的名称是:"+name); } }
package ioc.iocsample; /** * 学生类 * @author lhy * */ public class Student { public int id; public String name; private School school; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public School getSchool() { return school; } public void setSchool(School school) { this.school = school; } }
<!-- Spring的配置文件 -->
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="school" class="ioc.iocsample.School"> <constructor-arg index="0"> <value>廊坊师院</value> </constructor-arg> </bean> <bean id="student" class="ioc.iocsample.Student"> <property name="id" value="001"/> <property name="name" value="张三"/> <property name="school" ref ="school"/> </bean> </beans>
/**
* 测试
*/
package ioc.iocsample; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student=(Student)factory.getBean("student"); student.getSchool().printInfo(); } }
其中,在程序中不用实例化学生类,学校类,直接由容器中的beanFactory创建,隐藏了创建了细节。
同时,程序中也不用关心学生类与学校类之间的依赖关系,而由容器来进行负责:在运行的时候,容器会把属性值及依赖关系注入学生类和学校类中的javabean中(其实在此School和Student就是一个javaBean。javaBean就是一个按照一定的原则封装的java类而已。)

浙公网安备 33010602011771号