理解SSH框架中的Spring

  在ssh项目中,是有明确分工的,spring的作用就相当于将struts和hibernate连接起来,是将两个没有关系的框架的特性,方法,action都放在spring的配置文件中使他们建立关系。取他门各自所长。而这些做法他们自己不知道,他们是听命于spring调度的,他的的任务只是做好自己的事情。
    这样做的好处就是任务结构分明,struts只管理显示与做什么,hibernate只关心怎么做,而spring就相当于领导,所以一切的类都要交给spring的工厂创建,这是一种良好的开发模式,体现了一种编程思想,最大的好处就是结构分明,便于维护,一旦项目出现问题,只修改spring文件,而不在你复杂的程序中去发现是谁在调用谁。

    简而言之,ssh框架总体是为了解耦合使用的,struts管理表示层,spring管理业务逻辑层,hibernate管理持久化层,3个框架互相不关联,spring调用hibernate、struts调用spring来做方法调用,好处在于spring面向接口的设计,只要你的接口不变,impl变动在配置文件中配置就好了,这样在工程实施后,可以实现软编码,在异地调用用的配置文件直接修改配置文件调用已经写好的类,来增加功能。

 

下面结合实例理解解容器,DIIOC,耦合,解耦等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配置文件中添加如下配置

<</SPAN>bean id="s1" class="com.hb.Soldier"></</SPAN>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默认使用单例的方式创建对象。可以通过修改的配置改变成其它创建方式。这个属性为Scope,称之为作用域或生命周期,它的值为singleton(单例,默认值),prototype(每次产生一个新的实例)等。

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

 

2.  注入方式有setter注入,构造注入方式,接口注入(不需掌握)。建议多使用Setter注入方式。

Setter注入

Soldier类中有一个属性name,如何在创建Soldier的时候使name的值变为”RANBO”?

配置如下:

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

<</SPAN>property  name="name"  value="RANBO"/>

</</SPAN>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;

    }

}

配置如下:

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

<</SPAN>constructor-arg  value="RANBO"></</SPAN>constructor-arg>

</</SPAN>bean>

测试结果同上。

 

3.  依赖

A对象使用了B对象的方法,AB产生依赖,称之为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)

我们运用Springsetter注入方式解决HandGunSoldier的耦合问题。修改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();

    }  

}

配置如下

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

<</SPAN>property name="handGun">

<</SPAN>ref bean="handgun"></</SPAN>ref>

</</SPAN>property>

</</SPAN>bean>

<</SPAN>bean id="handgun" class="com.hb.HandGun"></</SPAN>bean>

到这里,我们已经降低了HandGunSoldier的部分依赖关系,至少在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();

    }  

}

配置如下

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

<</SPAN>property name="weapon">

<</SPAN>ref bean="handgun"></</SPAN>ref>

</</SPAN>property>

</</SPAN>bean>

<</SPAN>bean id="handgun" class="com.hb.HandGun"></</SPAN>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 ,这就是依赖注入了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值