原文: https://blog.csdn.net/xyz_dream/article/details/52821561
接触Java EE方面的朋友,尤其是对于入门级别的同学,对于Java EE框架spring+spring mvc+mybatis(SSM)或者spring+struts2+hibernate(SSH)三大框架中,对于Spring是最难以理解的。为何这么说?因为博主在学习这个方面的时候,和许多同学都产生过这个困惑,所以百度上都会有类似”Spring是做什么的?谁能讲讲Spring到底是什么?”这些问题,相信也会有很多入门的同学会有相同的疑惑。
对于上面在百度上问到的问题,一些回答就是copy百度百科的东西贴上去,或者是用着例如IOC,AOP等术语解释给提问者,并且也不解释IOC,AOP等名词的意思。的确可能有些人是大牛,不愿在这个问题上去花费他的时间,这也无可厚非,但是有些就是故意使用一些入门者不懂的名词,来显摆一下自己是有多厉害,多么的高深。下面这篇文章就讲讲Spring的那些事。
其实Spring主要处理的两大方面在于IOC(控制反转/依赖注入),AOP(面向切面)。什么是IOC(Inversion of Control)呢?解决的是解耦的问题,高质量的代码一般都要求低耦合,高内聚的特点,这样会利于维护和测试。着重谈一谈耦合度,耦合: 举个简单得例子,例如指的是两个子系统或者类彼此之间相互依赖(关联)的程度,这个程度越低,就说耦合度越低,关联越密切,则是耦合度越高。两个类之间,耦合度在不影响整个工程的情况下,尽量要降到最低,注意一个词”尽量”,而不是说全部解耦到一点关联都没有,那就是相互都独立的东西,怎么还可能去构成一个工程呢?
关于耦合度的概念大家了解那么一点了,下面开始说Spring要做的事IOC。
现在有2个类Student和Teacher类,并且一个学生只能有一个老师,这样的逻辑。普通处理的代码如下:
package xyz.dream.demo
//面向接口编程
interface Person{
public void eat();
}
//教师类
class Teacher implements Person {
private String name;
private String number;
public eat(){
System.out.println(“吃饭”);
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public String getNumber(){
return number;
}
public void setNumber(String name){
this.number=number;
}
}
//学生类
class Student{
private Person teacher=new Teacher();//普通的硬代码产生teacher对象,使用spring后,不需要写new Teacher();这段代码了,在spring配置文件配置就行
public void setTeacher(Teacher teacher){
this.teacher=teacher;
}
public Teacher getTeacher(){
return teacher;
}}
此时,从代码中可以看出,Student类依赖于Teacher,就是说先是产生过属性teacher这个对象之后,Student对象才会完整和使用。但是现在有一个问题来了。假如我的
Teacher类的类名改了,我们还得去修改有产生Teacher类对象的地方。有人说改了就是了,没多大的点事。在代码量小的时候的确也不是什么难事,但是你得考虑一个大型项
目一改一个地方,就会牵一发而动全身,各式各样的错误就会出现,不利于调试和维护。
假如我们使用spring的话,硬编码的那段代码就可以省略了,在配置文件中配置把Teacher对象注入进来就行了。来看看配置的spring.xml的信息,替换一下上面的那段代码。
<?xml version=”1.0” encoding=”UTF-8”?>
<beans xmlns=”http://www.springframework.org/schema/beans"
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance"
xmlns:context=”http://www.springframework.org/schema/context"
xmlns:mvc=”http://www.springframework.org/schema/mvc"
xmlns:tx=”http://www.springframework.org/schema/tx"
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
“
>
<!–在spring容器中,产生一个名叫teacher的Teacher对象,启动tomcat后配置启动引入spring配置文件后,spring容器会创建,之后会执行下面的配置–>
<bean id=”teacher” class=”xyz.dream.demo.Teacher”></bean>
<!–在spring容器中,创建名叫student的Student类的对象,并且给一个属性叫teacher注入名为teacher的对象,就是上面那个JAVA Bean对象–>
<bean id=”student” class=”xyz.dream.demo.Student”>
<property name=”teacher” ref=”teacher”>
</bean>
</bean>
new Teacher();这段代码就可以省略了,如果以后你想修改Teacher类名,通过配置文件修改class的值就行了,是不是方便多了?
通过下面的代码测试一下,studentd的一个对象是否会存在于内存之中,我们把它取出来看看student这个会正常地运行吗?
public class Test {
public static void main(String[] args){
//加载spring配置文件,获取到容器对象
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(“spring.xml”);
//从容器中取出名为studnet的对象
/ <bean id=”student” class=”xyz.dream.demo.Student”>
<property name=”teacher” ref=”teacher”>
</bean>
/
Student student=(Student) applicationContext.getBean(“student”);
student.getTeacher().eat();
}
}
控制台会输出”吃饭”这个词,表明了我们的teacher这个对象注入到studnet对象的teacher的那个属性当中去了,加载配置文件后,spring创建的两个对象都在内存中,我们
通过容器对象取出studnet这个对象无误,表明了spring这个容器是可以做到这一点的,减少了硬编码通过new 的形式来获取对象。
spring功能很强大,我这个只是其中一个小例子,是对入门的同学起到一点点对spring理解的作用,希望能帮助到你们。IOC(依赖注入/控制反转)这个小案例,大家看后能多
多少少有那么点理解。笔者水平有限,若出现某些知识点理解错误的地方希望海涵,谢谢!