Spring 实例入门

Spring 实例入门


本文结合实例理解解容器,DI,IOC,耦合,解耦等Spring所涉及的概念,同时了解Spring的最基本也是最核心的使用方法。
1. Spring容器
Spring容器负责对象的实例化,对象生命周期的管理,被Spring管理的对象称之为Bean。
例如有Soldier类需要交由Spring容器管理,我们先编写类

package com.hb;
public class Soldier {
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

在Spring配置文件applicationContext.xml中添加如下配置

<bean id="s1" class="com.hb.Soldier"></bean>

初始化Spring容器

public class Test {
	public static void main(String[] args) {
	          ApplicationContext context = new 
	          ClassPathXmlApplicationContext("applicationContext.xml");
	}
}

从Spring容器中取得对象实例

Soldier s1 = (Soldier) context.getBean("s1");

Spring默认使用单例的方式创建对象。可以通过修改<bean>的配置改变成其它创建方式。这个属性为Scope,称之为作用域或生命周期,它的值为singleton(单例,默认值),prototype(每次产生一个新的实例)等。

<bean id="s1" class="com.hb.Soldier" scope="prototype"></bean>

2. 注入方式有setter注入,构造注入方式,接口注入(不需掌握)。建议多使用Setter注入方式。
Setter注入:
Soldier类中有一个属性name,如何在创建Soldier的时候使name的值变为”RANBO”?
配置如下:

<bean  id="s1"  class="com.hb.Soldier">
       <property  name="name"  value="RANBO"/>
</bean>

这样创建的Soldier对象的name属性就有值了,测试代码:

public static void main(String[] args) {
	ApplicationContext context = new 
	ClassPathXmlApplicationContext("applicationContext.xml");
	Soldier s1 = (Soldier) context.getBean("s1");
	System.out.println(s1.getName());
}

构造注入:
我们先修改下Soldier类,给它添加一个构造方法:

package com.hb;
public class Soldier {
	private String name;

	public Soldier(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}
}

配置如下:

<bean  id="s1"  class="com.hb.Soldier">
     <constructor-arg  value="RANBO"></constructor-arg>
</bean>

测试结果同上。

3. 依赖
当A对象使用了B对象的方法,A对B产生依赖,称之为A依赖B。下面的例子中Soldier类依赖HandGun类。

package com.hb;
/**
 * 士兵类
 */
public class Soldier {
	/**
	 * 打仗
	 */
	public void fight(){
		HandGun handGun = new HandGun();
		handGun.killEnemy();
	}	
}
package com.hb;
/**
 * 枪类
 */
public class HandGun {
	/**
	 * 枪杀敌
	 */
	public void killEnemy(){
		System.out.println("枪杀敌");
	}
}

 当HandGun发生变化时,必然导致Soldier必须做相应修改,同时,当Soldier需要使用OtherGun时也必须重新编写代码,导致代码重用度不高。

当对象之间的依赖关系很强时(耦合),会使程序代码死板,不利于后期的维护和扩展。降低对象之间的依赖关系称之为解耦。Spring能够很好的解决这一问题。

4. 控制反转(Inversion of Control,简称IOC)和依赖注入(Dependence Inject简称DI)
我们运用Spring的setter注入方式解决HandGun和Soldier的耦合问题。修改Soldier的代码,将HandGun定义为Soldier的属性并提供setter方法:

package com.hb;
/**
 * 士兵类
 */
public class Soldier {
	private HandGun handGun;
	
	
	public void setHandGun(HandGun handGun) {
		this.handGun = handGun;
	}
	/**
	 * 打仗
	 */
	public void fight(){
		handGun.killEnemy();
	}	
}

配置如下

<bean  id="s1" class="com.hb.Soldier">
    <property name="handGun">
         <ref bean="handgun"></ref>
    </property>
</bean>
<bean id="handgun" class="com.hb.HandGun"></bean>

到这里,我们已经降低了HandGun和Soldier的部分依赖关系,至少在Soldier中不用再自己去实例化HandGun了。然而并没有彻底解决问题,Soldier中仍然可以看到HandGun类,因此我们使用接口进一步改进代码:

package com.hb;
/**
 * 武器接口
 */
public interface Weapon {
	/**
	 * 杀敌
	 */
	void killEnemy();
}
package com.hb;
/**
 * 枪类
 */
public class HandGun implements Weapon{
	/**
	 * 枪杀敌
	 */
	public void killEnemy(){
		System.out.println("枪杀敌");
	}
}
package com.hb;
/**
 * 士兵类
 */
public class Soldier {
	private Weapon weapon;
	
	
	public void setWeapon(Weapon weapon) {
		this.weapon = weapon;
	}
	/**
	 * 使用武器打仗
	 */
	public void fight(){
		weapon.killEnemy();
	}	
}

配置如下

<bean id="s1" class="com.hb.Soldier">
     <property name="weapon">
          <ref bean="handgun"></ref>
     </property>
</bean>
<bean id="handgun" class="com.hb.HandGun"></bean>
测试:

相关推荐