引言:
从上一节的简单介绍中,我们知道了Spring的概念和项目的创建,并且了解了Spring是怎样工作的。在这一节中,我们要讲的内容有(1)Spring对bean关系的维护(2)ioc是什么(3)di是什么
一、Spring的关系维护
我们再来创建一个类,叫做ByeService.class,并且将其作为UserService.class的一个属性,这样就将这两者人为的发生了关系。
package rogue.service;
public class UserService {
private String name;
private ByeService byeService;
public ByeService getByeService() {
return byeService;
}
public void setByeService(ByeService byeService) {
this.byeService = byeService;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("hello"+name);
byeService.sayBye();
}
}
然后,我们将两者之间的关系体现在配置文件中:
圈1指的是:第二个属性的名称
圈2指的是:第二个属性和哪个bean是关联的
圈3指的是:bean的id。通过这个id,程序可以调用这个bean
这三个圈的名称是一样的,但是意思却大相径庭,所以还需要理解了各种配置的含义,这样才能做到正确的配置。
经过这样的配置,我们成功的将UserService中有了ByeService的方法,因此我们再用UserService来调用sayHello方法的时候就不会出现空指针的异常了。
下面来说说Spring框架原理(Spring框架什么时候被加载,Spring中创建的bean什么时候被创建,bean与bean之间的关系怎样被维护):
ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext.xml");
当上面一句话执行的时候,Spring容器被创建,同时applicationContext中配置的bean对象就会在内存中被创建。(从上一节中我们也知道bean对象的创建是通过反射实现的,看来反射真是个好东西啊!不过在我们菜鸟的世界是很难接触到反射的,因为它主要是用来做框架的,目前为止,我也只有在工厂类中使用到反射。不过反射打破了面向对象的重要特性——“封装”,使得程序员可以窥探程序内部的世界,还是相当危险的。)
那么,既然用到了引用,我们可能会有这样的疑惑(我才不管你有没有,我就说是有!╭(╯^╰)╮),我们的引用在内存中到底是怎样和调用者发生关系(请不要误会)的呢?有一种可能是这样的,在applicationContext容器加载的时候,是首先加载没有引用的bean(也就是从下往上加载的),这样当调用者调用的时候会在内存中找到该bean,从而成功的引用他;另一种可能是容器按照正常顺序加载,从上往下,当有引用关键字“ref”的时候,如果引用的bean还没有被加载到内存中,那就保留,当引用的bean加载时,该bean会将自己的地址传给调用者,从而关联在一起。
下面是框架的原理图:
二、IOC(控制反转)
所谓的控制反转(inverse of control),就是把创建对象(bean)和维护对象的关系的权利从程序中转移到Spring容器的文件(applicationContext.xml)。
三、DI(依赖注入)
实际上,DI和IOC是用一个概念,Spring的设计者认为,地更能表达Spring的核心技术。
关于控制反转和依赖注入,以上理解都是很浅显的,具体细节请移步:
http://blog.csdn.net/bestone0213/article/details/47424255
四、从上面的介绍中我们也可以知道,applicationContext作为一个容器,对bean的加载起着关键的作用,不过他在一个项目中是唯一的,因此,我们应该使用单例模式对其进行封装。
package com.Utils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
final public class ApplicationContextUtils {
private static ApplicationContext aContext = null;
private ApplicationContextUtils(){
}
static{
aContext = new ClassPathXmlApplicationContext("applicationContext.xml");
}
public static ApplicationContext getApplicationContext() {
return aContext;
}
}
这样我们以后在使用时直接调用就可以了。