一:spring的基本特征java
Spring是一个很是活跃的开源框架;它是一个基于Core来架构多层JavaEE系统的框架,它的主要目的是简化企业开发。Spring以一种非侵入式的方式来管理你的代码,Spring提倡“最少侵入,这也意味着你能够适当的时候安装或卸载Spring。node
二:开发Spring所须要的工具程序员
1.Spring的jar包spring
到http://www.springsource.org/download下载spring,而后进行解压缩,在解压目录中找到下面jar文件,拷贝到类路径下 编程
若是使用了切面编程(AOP),还须要下列jar文件 lib/aspectj/aspectjweaver.jar和aspectjrt.jar lib/cglib/cglib-nodep-2.1_3.jar tomcat
若是使用了JSR-250中的注解,如@Resource/@PostConstruct/@PreDestroy,还须要下列jar文件 lib\j2ee\common-annotations.jar 注:JSR(Java 规范请求)是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人均可以提交JSR(Java 规范请求),以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。session
2.Spring的配置文件架构
默认状况下是applicationContext.xml文件。能够建不少XML文件,工程中通常都是这样配置的。mvc
三:Spring基本功能及案例详解app
1.Spring的IOC
SpringIOC(控制反转):把对象的建立,初始化,销毁等工做交给Spring容器来作。由Spring容器控制对象的生命周期。
步骤:A:启动Spring容器;B:从Spring容器中把对象取出来;C:最后,对象调用实际的业务方法。
A:启动Spring容器:
在类路径下寻找配置文件来实例化容器:ApplicationContext context = new ClassPathXmlApplicationContext("配置文件类路径");
经过这种方式加载。须要将spring配置文件放到当前项目的classpath路径下。classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。
在文件系统路径下寻找配置文件来实例化容器:ApplicationContext context = new FileSystemXmlApplicationContext("配置文件系统路径");
注:常常采用第一种方式启动Spring容器。
B:从Spring容器中把对象取出来:
context.getBean("配置文件中bean的id"); 如:HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
C:对象调用实际的业务方法:
helloWorld.hello();
1.1.Spring容器建立对象的方式
A:默认的状况下是调用该类默认的无参构造函数来建立类的对象。
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-creatobject.xml
业务类HelloWorld.java
客户端代码:
由此看出:若是业务类HElloWorld.java又写了该类的有参构造函数,此时就覆盖了默认的无参构造函数。这样就致使Spring容器在建立该类的对象时失败。由于默认的是调用该类的默认无参构造函数,而此时又找不到无参构造函数了,因此就建立对象失败。
B:Spring容器利用静态工厂方法建立类对象。
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-creatobject-method.xml
业务类HelloWorld.java
静态工厂类方法:
客户端代码:
C:Spring容器利用实例工厂方法建立对象
再次不作案例分析,记住便可。
最后说明一下:spring配置文件中,只要是一个bean就会为该bean建立对象(默认是调用该类的默认构造函数建立对象)
1.2.Spring配置文件中别名的用法
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-alias.xml
业务类HelloWorld.java
客户端代码:
由此看出:经过配置文件中的配置,能够达到在一个地方命名,在多个地方使用不一样的名字的效果。
1.3.Spring容器建立对象的时机
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-creatobject-when.xml
业务类HelloWorld.java
客户端代码:
执行结果:
由执行结果可看出:在单例状况下(默认就是单例,关于单例,下面会讲到):
A:在默认状况下,启动spring容器的时候(ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml)),就调用该类的无参构造函数建立对象。因此spring容器建立对象的时机是:启动spring容器时建立。
B:在spring的配置文件bean中有一个属性lazy-init="default/false/true":
a:若是lazy-init="default/false",在启动spring容器的时候建立对象。
b:若是lazy-init="true",在获取对象的时候建立对象,即context.getBean()时,建立对象。
a与b的意义:
在第一种状况下能够在启动spring容器的时候,检查spring配置文件的正确性。若是再结合tomcat,若是spring容器不能正常启动整个tomcat就不能正常启动。可是这样的缺点是把一些bean过早的放在了内存中,若是有数据,则对内存来讲是一个消耗。在第二种状况下,能够减小内存的消耗,可是不容易检查出配置文件中的错误,排错比较困难。
1.4.Spring容器中bean的单例与多例
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-creatobject-scope.xml
业务类HelloWorld.java
客户端代码:
执行结果:
在配置文件的bean中的scope="singleton"的状况下(即默认状况下):
在配置文件的bean中的scope="prototype"的状况下:
从执行的结果,咱们来总结概括一下:
从第一个执行结果看出,由spring容器产生的bean默认是单例的。打印结果看出,两次分别获取的bean结果是同样的。而且单例模式下,spring容器在启动的时候建立对象。
从第二个执行结果看出,若果将配置文件中的bean的scope值修改成“prototype”,那么由spring容器产生的bean就是多例的。打印结果看出,两次分别获取的bean结果是不同的。而且在多例模式下,spring容器在context.getBean(),即获取对象的时候建立对象。这里有两次获取bean,因此打印出两个:new instance-----scope
综上:能够在spring的配置文件 ,scope的值进行修改="singleton/prototype/request/session/global session/global" ,若是spring的配置文件的scope为“prototype”,则在获得或者说从spring容器获取该bean的时候才建立对象。
1.5.Spring容器中对象的生命周期
案例
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-initdestory.xml
业务类HelloWorld.java
客户端代码:
执行结果:
由执行结果的顺序能够看出:在单例状况下,即默认scope="singleton"的时候
a:spring容器在启动的时候建立对象;
b:spring容器执行init方法;
c:程序员调用本身的业务方法;
d:当spring容器关闭的时候执行destory方法。
spring容器:ApplicationContext applicationContext = new ClassPathXmlApplicationContext("");
它的关闭:须要将applicationContext转化一下:
ClassPathXmlApplication cpxa = (ClassPathXmlApplicationContext) applicationContext;
cpxa.close(); 这样才能关闭spring容器,执行destory方法。
注意:当scope=“prototype”的时候(即多例的状况下),spring容器不会执行destory()方法。
2.Spring的DI(依赖注入)
springDI:理解为依赖注入,俗称给属性赋值。
日常中,咱们给类的属性赋值,无非两种方式:1.调用类的set,get方法;2.调用类的构造方法。好比下面一个类中的属性类型,几乎表明了全部类型:
public class Person{
private Long pid;
private String pname;
private Student student;
private List lists;
private Set sets;
private Map map;
private Properties properties;
//set,get方法
}
说明:一个类中的全部属性均可以采用SpringDI的方式赋值,但并非全部的属性都适合赋值。
2.1.调用类的set,get方法
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-di-set.xml
业务类Person.java
业务类Student.java
客户端代码:
执行结果:
总结:从业务中的标注看,
1.我这里使用了本身编写的工具类SpringInit.java,是为了方便2的使用;
工具类的代码以下:
public class SpringInit{
public static ApplicationContext context;//spring容器
//静态代码块,在类加载的以后执行,只执行一次
static{
context = new ClassPathXmlApplicationContext("applicationContext.xml");//启动spring容器
}
}
而后个人客户端类继承了这个工具类。
结合配置文件和执行结果,看出是经过set方法赋值的。首先建立对象解析全部的property,把name解析出来,拼接成set方法,把value和ref解析出来并赋值。
2.2.调用类的构造方法
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-di-constructor.xml
业务类同1.1中的业务类相同,只是Person类中添加一个构造方法:
public Person(String pname,Student){
this.pname = pname;
this.student = student;
}
客户端代码:
执行结果:
总结:构造函数的方式赋值:
2.3.spring的IOC与DI的意义
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-document.xml
业务类:
ducument接口:
三个实现接口的类:
------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
文档管理类DocumentManager.java
客户端代码:
执行结果:
从例子能够看出,Spring的IOC与DI的完美结合,是其作到了真正的面向接口编程。若是咱们想读写Excel或者Word,只须要修改配置文件中的传入参数便可。而传统的方式是不彻底面向接口的编程,把实现类暴露给客户端了。
2.3.spring的IOC与DI实现mvc的模拟例子
案例:
Spring的主配置文件:applicationContext.xml(由于我这里将会讲到不少模块,因此我用一个主配置文件去加载各个模块的配置文件):
具体业务模块配置文件applicationContext-mvc.xml
业务类:
服务层接口与实现:
-----------------------------------------------------------------------------------------------
dao层接口与实现:
------------------------------------------------------------------------------------------
控制层action
客户端代码:
执行结果:
从例子能够看出,Spring的IOC与DI的完美结合,是其作到了真正的面向接口编程。这里的依赖注入都采用了set的方式注入的。