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类而已。)

posted @ 2017-07-13 14:06  zhengmengen  阅读(195)  评论(0)    收藏  举报