服务器之家

服务器之家 > 正文

浅谈SSH框架中spring的原理

时间:2020-07-27 14:30     来源/作者:jingxian

在ssh项目中,是有明确分工的,spring的作用就相当于将struts和hibernate连接起来,是将两个没有关系的框架的特性,方法,action都放在spring的配置文件中使他们建立关系。取他门各自所长。而这些做法他们自己不知道,他们是听命于spring调度的,他的的任务只是做好自己的事情。

这样做的好处就是任务结构分明,struts只管理显示与做什么,hibernate只关心怎么做,而spring就相当于领导,所以一切的类都要交给spring的工厂创建,这是一种良好的开发模式,体现了一种编程思想,最大的好处就是结构分明,便于维护,一旦项目出现问题,只修改spring文件,而不在你复杂的程序中去发现是谁在调用谁。

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

下面结合实例理解解容器,DI,IOC,耦合,解耦等Spring所涉及的概念,同时了解Spring的最基本也是最核心的使用方法。

1.Spring容器

Spring容器负责对象的实例化,对象生命周期的管理,被Spring管理的对象称之为Bean。

例如有Soldier类需要交由Spring容器管理,我们先编写类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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容器

?
1
2
3
4
5
6
7
8
9
10
11
public class Test {
 
  public static void main(String[] args) {
 
ApplicationContext context = new
 
ClassPathXmlApplicationContext("applicationContext.xml");
 
  }
 
}

从Spring容器中取得对象实例

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

 

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

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

 

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

Setter注入:

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

配置如下:

?
1
2
3
4
5
<</SPAN>bean id="s1" class="com.hb.Soldier">
 
<</SPAN>property name="name" value="RANBO"/>
 
</</SPAN>bean>

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

?
1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
 
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
 
Soldier s1 = (Soldier) context.getBean("s1");
 
System.out.println(s1.getName());
 
}

构造注入:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.hb;
 
public class Soldier {
 
  private String name;
 
 
 
  public Soldier(String name) {
 
    this.name = name;
 
  }
 
 
 
  public String getName() {
 
    return name;
 
  }
 
}

配置如下:

?
1
2
3
4
5
<</SPAN>bean id="s1" class="com.hb.Soldier">
 
<</SPAN>constructor-arg value="RANBO"></</SPAN>constructor-arg>
 
</</SPAN>bean>

测试结果同上。

3. 依赖

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.hb;
 
 
 
public class Soldier {
 
  private HandGun handGun;
 
  
 
  
 
  public void setHandGun(HandGun handGun) {
 
    this.handGun = handGun;
 
  }
 
  
 
  public void fight(){
 
    handGun.killEnemy();
 
  }
 
}

配置如下

?
1
2
3
4
5
6
7
8
9
10
11
<</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>

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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();
 
  }
 
}

配置如下

?
1
2
3
4
5
6
7
8
9
10
11
<</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>

测试:

?
1
2
3
4
5
6
7
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,这就是依赖注入了。

以上这篇浅谈SSH框架中spring的原理就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享 2020-04-07
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-05-20
男生常说24816是什么意思?女生说13579是什么意思?
男生常说24816是什么意思?女生说13579是什么意思? 2019-09-17
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意 2019-07-07
返回顶部