JavaWeb Spring开发入门深入学习
1 spring基本特征
spring是一个非常活跃的开源框架;它是一个基于core来构架多层javaee系统的框架,它的主要目地是简化企业开发.
spring以一种非侵入式的方式来管理你的代码,spring提倡”最少侵入”,这也就意味着你可以适当的时候安装或卸载spring,spring让java亮了。 (开放–闭合原理),这里是闭原则。
2 开发spring所需要的工具
(这里先将spring2.5 ,后面3.0)
2.1 spring的jar包
到http://www.springsource.org/download下载spring,然后进行解压缩,在解压目录中找到下面jar文件,拷贝到类路径下
—spring的核心类库 在spring文档的dist下 dist\spring.jar
—引入的第三方类库 都spring文档的lib下,lib\jakarta-commons\commons-logging.jar
—如果使用了切面编程(aop),还需要下列jar文件 lib/aspectj/aspectjweaver.jar和aspectjrt.jarlib/cglib/cglib-nodep-2.1_3.jar
—如果使用了jsr-250中的注解,如@resource/@postconstruct/@predestroy,还需要下列jar文件lib\j2ee\common-annotations.jar
注:jsr(java 规范请求)是指向jcp(java community process)提出新增一个标准化技术规范的正式请求。任何人都可以提交jsr(java 规范请求),以向java平台增添新的api和服务。jsr已成为java界的一个重要标准
2.2 spring配置文件
默认情况下是applicationcontext.xml文件。可以建立很多xml文件,工程中一般都是这样配置的。(src目录下建)
3 spring基本功能详解
3.1 springioc
spring的控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。
步骤:
•a. 启动spring容器
1、 在类路径下寻找配置文件来实例化容器
可以在整个类路径中寻找xml文件
* 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下
* classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。
2、 在文件系统路径下寻找配置文件来实例化容器
spring的配置文件可以指定多个,可以通过string数组传入。
注:经常用第一种方法启动容器
•b. 从spring容器中提取对象
spring 容器结构:
3.2 别名
<beans> <alias name="person" alias="p"/>//alias这里是别名,可以通过p,得到person这个bean. <bean name="person" class="cn.itcast.aliasspring.person"/> </beans>
通过这样的配置,可以达到在一个地方命名,在多个地方使用不同的名字的效果。
3.3 spring容器内部对象
1 创建对象的方式
1.1 无参构造函数
<bean id="helloworld" class="com.itheima10.spring.createobject.helloworld"></bean>
1.2 静态工厂方法
<bean id="helloworld2" class="com.itheima10.spring.createobject.method.helloworldfactory"
factory-method="getinstance"></bean>
1.3 实例工厂方法
<bean id="helloworldfactory" class="com.itheima10.spring.createobject.method.helloworldfactory2"></bean>
<bean id="helloworld3" factory-bean="helloworldfactory" factory-method="getinstance"></bean>
记住概念即可,用的最多的是第一种方法,但是和别的工具集成时,用的是实例工厂模式。
实例:
配置applicationcontext.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" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- 把一个类放入到spring容器中,该类就称为一个bean --> <!-- bean描述了一个类 id 唯一的标示 class 类的全名 --> <bean id="helloworld" class="com.itheima10.spring.createobject.helloworld"></bean> <!-----------------------别名--------------------------------------> <!-- name的属性和bean的id匹配 alias 别名 --> <alias name="helloworld" alias="狗蛋"/> <alias name="helloworld" alias="*"/> <!-----------------------静态工厂方法--------------------------------------> <!-- 把helloworldfactory放入到spring容器中 factory-method 工厂方法 --> <bean id="helloworld2" factory-method="getinstance" class="com.itheima10.spring.createobject.method.helloworldfactory"></bean> <!-----------------------实例工厂方法--------------------------------------> <!-- 把helloworldfactory2放入到spring容器中 factory-bean 指明了工厂bean factory-method 指明了该工厂bean中的方法 --> <bean id="helloworldfactory" class="com.itheima10.spring.createobject.method.helloworldfactory2"></bean> <bean id="helloworld3" factory-bean="helloworldfactory" factory-method="getinstance"></bean> </beans>
建立实体类helloworld
package com.itheima10.spring.createobject; public class helloworld { public void hello(){ system.out.println("hello"); } }
建立静态工厂helloworldfactory
package com.itheima10.spring.createobject.method; public class helloworldfactory { public static helloworld getinstance(){ system.out.println("static method"); return new helloworld(); } }
建立实体工厂helloworldfactory2
package com.itheima10.spring.createobject.method; public class helloworldfactory2 { /** * 必须先创建工厂对象,才能调用该方法 * @return */ public helloworld getinstance(){ return new helloworld(); } }
编写测试方法createobjectmethodtest
package com.itheima10.spring.createobject.method; import org.junit.test; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; /** * 第二种和第三种产生方式能看明白就ok了 * @author zd * */ public class createobjectmethodtest { /** * 在默认情况下,spring容器调用的是一个类的默认的构造函数创建对象 */ @test public void testcreateobject_default(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); helloworld helloworld = (helloworld)context.getbean("helloworld"); helloworld.hello(); } /** * 利用静态工厂创建对象 * <bean id="helloworld2" factory-method="getinstance" class="com.itheima10.spring.createobject.method.helloworldfactory"></bean> spring容器做的事情: 利用helloworldfactory类调用了getinstance方法 */ @test public void testcreateobject_staticfactory(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); helloworld helloworld = (helloworld)context.getbean("helloworld2"); helloworld.hello(); } /** * 实例工厂方法创建对象 * <bean id="helloworldfactory" * class="com.itheima10.spring.createobject.method.helloworldfactory2"></bean> * <bean id="helloworld3" factory-bean="helloworldfactory" factory-method="getinstance"></bean> spring容器内部做的事情: 1、创建一个helloworldfactory对象 2、由该对象调用getinstance产生helloworld对象 */ @test public void testcreateobject_instancefactory(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); helloworld helloworld = (helloworld)context.getbean("helloworld3"); helloworld.hello(); } }
2 对象的scope
对象的scope有两个属性:singleton 与prototype。singleton表示单例
2.1 singleton(默认值)
在每个spring ioc容器中一个bean定义只有一个对象实例(共享)。
2.2 prototype
允许bean可以被多次实例化(使用一次就创建一个实例) . spring不能对一个prototype bean的整个生命周期负责.这就意味着清楚prototype作用域的对象并释放任何prototype bean所持有的昂贵资源都是客户端的责任。
<bean id="helloworld" class="com.itheima10.spring.scope.helloworld" scope="singleton"></bean>
<bean id="helloworld" class="com.itheima10.spring.scope.helloworld" scope="prototype"></bean>
建立helloworld类
public class helloworld { public list<string> lists = new arraylist<string>(); public helloworld(){ system.out.println("new instance"); } public void hello(){ system.out.println("hello"); } }
建立测试类scopetest
package com.itheima10.spring.scope; import org.junit.test; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; public class scopetest { /** * 把一个bean放入到spring容器中,默认的是单例 * 如果一个类放入到spring容易中,而这个类是单例的,那么该类中的属性将会成为共享的 */ @test public void testcreateobject_scope_default(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); helloworld hello1 = (helloworld)context.getbean("helloworld"); hello1.lists.add("aaaa"); hello2= (helloworld)context.getbean("helloworld"); hello2.lists.add("bbbb"); system.out.println(helloworld.lists.size());//2,并且只输出一次new instance } /** * 如果spring的配置文件如下: * <bean id="helloworld" class="com.itheima10.spring.scope.helloworld" scope="prototype"></bean> 那么spring容器会为创建多个对象 */ @test public void testcreateobject_scope_prototype(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); helloworld hello1 = (helloworld)context.getbean("helloworld"); hello1.lists.add("aaaa"); hello2= (helloworld)context.getbean("helloworld"); hello2.lists.add("bbbb"); system.out.println(helloworld.lists.size());//1,并且只输出两次new instance } }
3 初始化bean时机
懒加载——默认情况下会在容器启动时初始化bean,但我们可以指定bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:
<bean id="xxx" class="cn.itcast.orderservicebean" lazy-init="true"/>
如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:
<beans default-lazy-init="true“ ...>
spring默认在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化的一部分,applicationcontext会自动创建并配置所有的singleton bean.通常情况下这是件好事。因为这样在配置中有任何错误能立即发现。
lazy-init 为false,spring容器将在启动的时候报错(比较好的一种方式)
lazy-init 为true,spring容器将在调用该类的时候出错。
配置applicationcontext.xml
<bean id="helloworld" class="com.itheima10.spring.createobject.when.helloworld" scope="prototype"></bean> </beans>
建立测试类createobjectwhentest
package com.itheima10.spring.createobject.when; import org.junit.test; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; public class createobjectwhentest { /** * 默认情况下的顺序 * 1、启动spring容器 * 2、创建helloworld对象 * 3、对象调用方法 * * <bean id="helloworld" class="com.itheima10.spring.createobject.when.helloworld"></bean> <bean id="helloworld2" class="com.itheima10.spring.createobject.when.helloworld"></bean> 因为在spring容器中声明了两个bean,所以spring容器要创建两个对象 说明: 如果struts2,hibernate,spring容器整合,如果spring的配置文件中出现错误 当 tomcat容器启动的时候,就会报错,错误会特别早的显示出来 如果一个bean存放了大量的数据,这种方式不好,有可能会把数据过早的停留在内存中 如果一个bean不是单例,那么不管怎么样配置,都在是context.getbean时才要创建对象 */ @test public void testcreateobject_when_default(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); context.getbean("helloworld"); } /** * <bean id="helloworld" class="com.itheima10.spring.createobject.when.helloworld" lazy-init="true"></bean> * 顺序 * 1、启动spring容器 * 2、context.getbean * 3、调用构造器函数创建对象 * 说明: 如果struts2,hibernate,spring容器整合,如果spring的配置文件中出现错误 只有当用到该bean的时候才会报错。 如果一个bean存放了大量的数据,需要的时候才要加载数据 */ @test public void testcreateobject_when_lazy(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); context.getbean("helloworld"); } }
4 init、destroy方法
spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。可以指定方法进行操作。
<bean id=“foo” class=“...foo” init-method=“setup” destory-method=“teardown”/>
当foo被载入到spring容器中时调用init-method方法。当foo从容器中删除时调用destory-method(scope = singleton有效)
编写helloworld
public class helloworld { public helloworld(){ system.out.println("new instance"); } public void init(){ system.out.println("init"); } public void destroy(){ system.out.println("destroy"); } public void hello(){ system.out.println("hello"); } }
编写测试类initdestroytest
package com.itheima10.spring.ioc.initdestroy; import org.junit.test; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; public class initdestroytest { /** * init-method="init" * 执行顺序: * 1、启动spring容器 * 2、创建helloworld对象 * 3、执行init方法 * spring容器内部自动执行的 * 4、对象调用方法 * 5、只有当spring容器关闭掉的情况下才能执行destroy方法 前提条件:bean是单例的 * 该方法也是由spring容器内部调用的 * 说明: * 如果一个bean不是单例的,则spring容器不负责对象的销毁。 * 在spring容器中,只有一个bean是单例的情况下,spring容器才要负责对象的创建、初始化、销毁工作 * 如果一个bean不是单例,spring容器只负责创建、初始化 */ @test public void testinitdestroy(){ applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml"); helloworld helloworld = (helloworld)context.getbean("helloworld"); helloworld.hello(); classpathxmlapplicationcontext applicationcontext = (classpathxmlapplicationcontext)context; applicationcontext.close(); } }
执行顺序图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
JavaWeb Spring开发入门深入学习
-
JavaWeb Spring依赖注入深入学习
-
JavaWeb Spring注解Annotation深入学习
-
使用IntelliJ IDEA开发学习1- 如何导入一个已有的项目 博客分类: Spring4.0学习
-
JavaWeb开发入门第二篇Tomcat服务器配置讲解
-
JavaWeb开发入门第一篇必备知识讲解
-
JavaWeb开发之Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架
-
JavaWeb开发入门第二篇Tomcat服务器配置讲解
-
JavaWeb开发入门第一篇必备知识讲解
-
JavaWeb开发之Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架