一、Spring是什么
Spring框架是一个容器框架,它可以管理里我们项目中的web层、业务层、DAO层、持久层和数据库这几个模块,spring容器可以配置可以配置各个层中的组件,并且维护各个bean之间的关系。那么,bean又是什么呢?bean可以是JAVA中的任何一个对象,他可以使一个JAVA对象,可以是一个service,可以是一个DAO,甚至可以表示一个数据源。说简单一点,bean就是JAVA对象的另外一种表示形式,一个bean代表一个JAVA对象。
下面是一个项目的框架图:
二、IOC/DI
IOC(inverse of control),中文叫做控制反转。它的意思是把创建和管理对象的业务从以前由程序管理转移到由spring容器管理。在以前开发中,我们需要对象时,都是在程序中new一个,一个对象的生命周期由程序说了算,在spring中对象的创建和管理有spring容器来完成,程序需要对象时不需要自己创建,直接向spring容器要就可以了,管理对象的过程也不需要程序干涉,也有spring容器来完成。举个不恰当的例子:就像共享单车的出现一样,以前没有共享单车,大家要骑自行车出行必须自己买一辆,自己的车出问题了,也要自己找人修。共享单车出现以后,买车和修车的任务就交给了共享单车企业,我们需要骑车出行时,只需要在想单车企业要一辆就可以了,至于其他的事情就不需要我们关心了。
DI(Dependency Injection),中文名叫做依赖注入。我理解的DI的意思就是把程序需要的对象关联到到该程序中的过程。DI其实就是IOC的另一种叫法,只是spring的设计者觉得IOC的概念过于抽象,不易于理解,也不能准确表达出spring设计的精髓,就重新给IOC起了一个别名。
三、开发spring的流程
1、引入spring的jar包。
2、创建配置文件applicationContext.xml,一般放在src目录下,该文件中引入xsd文件。
3、配置bean
<bean id="checkUser1" class="com.java.service.CheckUser1">
<property name="name" value="jack"/>
</bean>
<bean id="checkUser2" class="com.java.service.CheckUser2">
<property name="userName" value="Tom"/>
</bean>
bean文件的作用是当加载spring容器时,spring就会自动创建一个对象并放入spring容器中。
一个baean标签代表创建的一个对象,id属性表示创建的对象的名字,class属性表示当前对象所属的类(必须用包名+类名)。一个property标签代表当前对象的一个属性,name表示属性名,必须和get方法的方法名中的属性名相同,还要注意命名规则,不符合命名规则的名称编译器会报错,value表示给当前属性赋的值。
4、创建Test类运行程序
//通过spring.xml文件创建一个spring容器,同时创建文件中配置的bean对象并放入容器中
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//通过容器得到需要的对象(反射机制)
//1.通过类名得到对象(不需要转型)
ValidateUser validateUser=context.getBean(CheckUser1.class);
//2.通过对象名(bean的name属性)得到对象(需要转型)
//ValidateUser validateUser = (ValidateUser) context.getBean("checkUser1");
//调用对象的方法
validateUser.check();
spring的运行原理图:
四、spring面向接口编程
spring提倡面向接口编程,通过接口可以试想层与层之间的解耦。那如何面向接口编程呢?举个例子说明:有一个接口中定义了一个字母转换的方法,有两个类分别去实现它,一个类实现将大写字母转换成小写字母的功能,一个类实现将小写字母转换成大写的功能。我们通过spring来实现它:
首先,定义接口:
public interface ChangeLetter {
public String change();
}
实现小写字母转换成大写的类:
public class UpperLetter implements ChangeLetter {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String change() {
str=str.toUpperCase();
return str;
}
}
实现大写字母转换成小写的类:
public class LowerLetter implements ChangeLetter {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String change() {
return str.toLowerCase();
}
}
在spring.xml文件中配置bean
<bean id="changeLetter" class="com.java.service.UpperLetter">
<property name="str" value="asGHsdfeFF"/>
</bean>
<!--
<bean id="changeLetter" class="com.java.service.LowerLetter">
<property name="str" value="HIOdfsafFJLKJdf"/>
</bean> -->
注意:将两个bean的id属性配置成一样的,所以两个bean不能同时出现
编写测试类
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//注意此处将对象类型转换成了接口类型,而不是实现类的类型
ChangeLetter change = (ChangeLetter) context.getBean("changeLetter");
System.out.println(change.change());
}
}
注意context.getBean()方法得到的对象转换成了接口的类型,而不是具体实现类的类型,因为有多个类实现了接口,每个类对接口定义的方法的实现都不一样,但是方法名都是一样的,转换成接口类型可以实现统一的方法调用。个人认为这里可以理解为面向对象思想中的多态的概念,即“父类的引用指向子类的对象”接口相当于父类,实现类相当于子类。这样实现以后,不管需要将小写字母转换成大写,还是讲大写字母转换成小写,都不需要更改程序代码,只需要在对应的xml文件中更改配置就可以实现相应的功能了。
五、总结
个人认为,刚入门spring一定要重点理解IOC/DI的概念,把以前的编程思想转换过来,要清楚spring的执行流程,对spring面向接口编程的思想也要有一定的理解。以上就是我对spring IOC和DI的理解,如果有什么不正确的地方,还望各位大佬指正。