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配置文件中添加如下配置
<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>
测试:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Soldier s1 = (Soldier) context.getBean("s1");
s1.fight();
至此,我们使用Spring很好的解决了HandGun和Soldier的耦合问题。Soldier类中再也看不到HandGun的踪影了,Soldier只依赖于接口,而最终Soldier还是使用了HandGun,这是为什么呢?Spring在这里管理了单个的对象,也管理了对象之间即Soldier和HandGun的依赖关系。原本是由Soldier控制HandGun的实例化的,转变为由Spring容器来控制,这里发生了控制权的转移,这就是控制反转控制反转控制反转控制反转(Inversion of Control,简称IOC)。当Soldier需要HandGun时,Spring会自动将HandGun对象注入给Soldier,这就是依赖注入依赖注入依赖注入依赖注入了。 看一下你是否已经有所领悟了: 假如“手-枪“已经不满足“士兵”的需要,我们需要将“手-枪”更换为更先进的“机枪”,你的程序如何编写呢?自己试一下吧!!
发表评论
-
webservice的cxf接口
2013-04-07 10:39 925CXF接口: 1.下载cxf-apache的工具包(附 ... -
java程序通信方式(未完)
2013-04-07 09:16 5711:采用J2EE 的Servlet 完成特定功能,部署To ... -
form提交
2013-02-28 16:46 0<html> <head> < ... -
jQuery怎样做开发(陆续更新)
2013-02-28 09:56 647调试环境 firefox firedebug ... -
eclipse撤销spring的方法
2012-10-26 14:51 918撤消MyEclipse对Spring的支持 1. 从 ... -
structs2--搭建
2012-10-24 13:43 0嗷嗷 -
target标签作用
2012-09-21 09:51 692_blank -- 在新窗口中打开链接 _parent -- ... -
js控制链接不在新窗口中打开
2012-09-20 10:35 998控制目的:禁止右键菜单 <script languag ... -
structs2与structs1.x的原理
2012-09-17 13:52 765当用户向Struts2发送请求时,FilterDispatch ... -
structs2的应用与structs1.x的区别
2012-09-17 10:43 1317【第1步】 安装Struts2 ... -
nginx服务器
2012-08-07 09:45 644Nginx 是一个很牛的高性能Web和反向代理服务器,它具 ... -
AJAX的处理
2012-08-06 12:16 757AJAX异步同步代码分析 var xmlhttp = ...
相关推荐
spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码spring仿写demo代码...
Spring开发指南——中文版,夏昕编写的,还不错。
spring cloud demo,消费者,生产者,注册中心,可以借鉴一下
适合初学者spring-boot——web笔记
最简单的 SpringCloud 教程—— 服务的注册与发现(Eureka) 1.创建服务注册中心 (Eureka Server) 2.创建一个服务提供者 (Eureka Client)
Spring依赖注入——java项目中使用spring注解方式进行注入.rar
演示spring框架演示——学习
spring boot整合JPA——demo
spring security demo2 spring security demo2 spring security demo2
京东T5级大牛带你解读Spring核心源码——1小时手写SpringMVC~ 需要更多往期录播资料可以联系我
Spring技术内幕——深入解析Spring架构与设计 (揭秘系列丛书) - 计文柯.mobi
利用maven构建的spring4.0框架的demo
springcloud
spring相关的demo,包含spring的ioc注入,aop的使用,mybatis的整合
这个Demo示范了怎么通过Spring的Validator接口来进行数据验证,包括Validator的复用、jsp错误信息的展示等。可参考本人博客: http://blog.csdn.net/oLanMoMo/article/details/50530352
spring Cloud demospring Cloud demospring Cloud demospring Cloud demospring Cloud demo
spring简单demo,包括aop和ioc的例子,包括注入,控制反转和面向切面的用法,希望能有帮助。
基于maven的cxf+spring简单demo,spring版本为4.1.6,cxf版本为3.0.8