什么是spring
spring是一个开源的轻量级的应用开发框架,它提供了IOC和AOP应用,可以减少组件之间的耦合度,即
解耦,spring容器可以创建对象并且管理对象之间的关系。
一:实例化spring容器对象
1:导入spring相关支持jar包
2:创建spring容器的配置文件applicationContext.xml,名称可以自己定义
内容如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:jdbc="http://www.springframework.org/schema/jdbc" 6 xmlns:jee="http://www.springframework.org/schema/jee" 7 xmlns:tx="http://www.springframework.org/schema/tx" 8 xmlns:jpa="http://www.springframework.org/schema/data/jpa" 9 xmlns:util="http://www.springframework.org/schema/util" 10 xmlns:mvc="http://www.springframework.org/schema/mvc" 11 xsi:schemaLocation=" 12 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 13 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 14 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 15 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 16 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 17 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd 18 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd 19 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> 20 21 </beans>
3:创建TestCase测试类,并引入Junit包
1 /** 2 * 3 */ 4 package com.hlcui.test; 5 6 import org.junit.Test; 7 import org.springframework.context.ApplicationContext; 8 import org.springframework.context.support.ClassPathXmlApplicationContext; 9 10 /** 11 * @author Administrator 12 * 13 */ 14 public class TestCase { 15 @Test 16 /**测试实例化spring容器对象*/ 17 public void testInitContext() { 18 String conf = "applicationContext.xml"; 19 ApplicationContext ac = new ClassPathXmlApplicationContext(conf); 20 System.out.println("spring容器对象:" + ac); 21 } 22 }
4:运行测试类,得到spring容器对象
二:使用spring容器创建javabean对象
1:在spring容器配置文件applicationcontext.xml中定义创建bean的声明
其中id代表bean的名称,也可以使用name属性名,id在配置文件中是唯一的,不可以重复,它就是给bean取一个名字,
class代表类,默认情况下spring会自动调用类无参构造方法创建对象,factory-method:工厂方法,类会调用工厂方法
常见对象,第三种情况是先通过java.util.GregorianCalendar无参构造创建calendar对象,然后通过调用calendar的
getTime方法创建date对象
1 <!-- 使用构造器实例对象 --> 2 <bean id="cal1" class="java.util.GregorianCalendar"></bean> 3 4 <!-- 使用静态工厂方式实例对象 --> 5 <bean id="cal2" class="java.util.Calendar" factory-method="getInstance"></bean> 6 7 <!-- 使用实例工厂方法创建对象 --> 8 <bean id="cal3" class="java.util.GregorianCalendar"></bean> 9 <bean id="date1" factory-bean="cal3" factory-method="getTime"></bean>
2:在TestCase测试类中,创建方法测试实例对象
1 /** 获取spring容器对象 */ 2 public ApplicationContext getApplicationContext() { 3 String conf = "applicationContext.xml"; 4 return new ClassPathXmlApplicationContext(conf); 5 }
spring容器对象调用getBean()方法,其中第一个参数是bean的id属性值,第二个参数是得到对象的类型
1 @Test 2 /**测试spring容器使用构造器实例对象*/ 3 public void testGregorianCalendar() { 4 ApplicationContext ac = getApplicationContext(); 5 Calendar cal1 = ac.getBean("cal1", Calendar.class); 6 System.out.println("cal1:" + cal1); 7 8 Calendar cal2 = ac.getBean("cal2", Calendar.class); 9 System.out.println("cal2:" + cal2); 10 11 Date date = ac.getBean("date1", Date.class); 12 System.out.println("date:" + date); 13 14 }
3:运行测试类,得到结果如下:
三:控制bean的实例化
1:bean对象的创建模式
a.创建ExampleBean对象
1 /** 2 * 3 */ 4 package com.hlcui.dao; 5 6 /** 7 * @author Administrator 8 * 9 */ 10 public class ExampleBean { 11 12 public ExampleBean() { 13 System.out.println("实例化ExampleBean对象..."); 14 } 15 16 public void execute() { 17 System.out.println("执行ExampleBean方法..."); 18 } 19 }
b.在spring容器配置文件中配置ExampleBean的bean
1 <!-- 实例化ExampleBean对象 --> 2 <bean id="exampleBean" class="com.hlcui.dao.ExampleBean"></bean>
c.在TestCase测试类中添加测试方法
1 @Test 2 /** 3 * 测试创建Bean对象的模式 4 * 比较两次创建的是否是同一个对象,如果为true,则是同一个对象,如果为false则不是 5 */ 6 public void testCreateExampleBean() { 7 ApplicationContext ac = getApplicationContext(); 8 ExampleBean eb1 = ac.getBean("exampleBean", ExampleBean.class); 9 ExampleBean eb2 = ac.getBean("exampleBean", ExampleBean.class); 10 System.out.println(eb1 == eb2); 11 }
运行测试类,结果如下:
可以看出spring容器默认实例化对象是单例模式,只创建一个对象。
d.如果修改配置,在bean中添加属性 scope="prototype"
1 <!-- 实例化ExampleBean对象 --> 2 <bean id="exampleBean" class="com.hlcui.dao.ExampleBean" scope="prototype"></bean>
在运行测试类结果为:
可以看出创建了两个对象,如果设置scope为原型模式,则不是单例模式。
2:Bean对象的初始化和销毁
a.在ExampleBean类中添加init()方法和destroy()方法
1 /** 2 * 3 */ 4 package com.hlcui.dao; 5 6 /** 7 * @author Administrator 8 * 9 */ 10 public class ExampleBean { 11 12 public ExampleBean() { 13 System.out.println("实例化ExampleBean对象..."); 14 } 15 16 public void execute() { 17 System.out.println("执行ExampleBean方法..."); 18 } 19 20 public void init() { 21 System.out.println("初始化ExampleBean对象..."); 22 } 23 24 public void destroy() { 25 System.out.println("销毁ExampleBean对象..."); 26 } 27 }
b.在spring配置文件中ExampleBean对应的bean元素上添加属性init-method="init"
1 <!-- 实例化ExampleBean对象 --> 2 <bean id="exampleBean" class="com.hlcui.dao.ExampleBean" 3 init-method="init" scope="prototype"></bean>
c.运行测试方法,结果如下:
可以看出调用了init()方法
如果想在spring容器销毁时调用destroy()方法,只需在配置文件bean元素上添加
属性destroy-method()
1 <!-- 实例化ExampleBean对象 --> 2 <bean id="exampleBean" class="com.hlcui.dao.ExampleBean" 3 init-method="init" destroy-method="destroy" scope="prototype"></bean>
测试方法中,将容器对象强制成AbstractApplicationContext对象,因为该对象定义了close()方法。
注:如果父类中的方法不能够满足业务要求时,可以将父类强制为子类,因为子类中拥有更多的方法。
1 @Test 2 /** 3 * 测试创建Bean对象的模式 4 * 比较两次创建的是否是同一个对象,如果为true,则是同一个对象,如果为false则不是 5 */ 6 public void testCreateExampleBean() { 7 ApplicationContext ac = getApplicationContext(); 8 ExampleBean eb1 = ac.getBean("exampleBean", ExampleBean.class); 9 ExampleBean eb2 = ac.getBean("exampleBean", ExampleBean.class); 10 System.out.println(eb1 == eb2); 11 12 /**将容器对象强制为AbstractApplicationContext对象,因为该对象定义了close方法*/ 13 AbstractApplicationContext aac = (AbstractApplicationContext) (ac); 14 aac.close(); 15 }
运行测试类,结果如下:
发现并没有调用销毁对象的destroy方法,这里需要注意,destroy方法,只有单例模式
下才会调用,这里是原型模式,所以在配置文件中将scope="prototype" 修改为
scope="singleton"
1 <!-- 实例化ExampleBean对象 --> 2 <bean id="exampleBean" class="com.hlcui.dao.ExampleBean" 3 init-method="init" destroy-method="destroy" scope="singleton"></bean>
这是再运行测试方法:
发现在卸载容器时,会调用destroy()方法。
d:如果将default-init-method="init"以及default-destroy-method="destroy"放到顶级的beans元素上,
那么它会作用于所有的bean对象。
3:bean对象的创建时机
a:注释掉一下代码
1 @Test 2 /** 3 * 测试创建Bean对象的模式 4 * 比较两次创建的是否是同一个对象,如果为true,则是同一个对象,如果为false则不是 5 */ 6 public void testCreateExampleBean() { 7 ApplicationContext ac = getApplicationContext(); 8 /*ExampleBean eb1 = ac.getBean("exampleBean", ExampleBean.class); 9 ExampleBean eb2 = ac.getBean("exampleBean", ExampleBean.class); 10 System.out.println(eb1 == eb2); 11 12 *//**将容器对象强制为AbstractApplicationContext对象,因为该对象定义了close方法*//* 13 AbstractApplicationContext aac = (AbstractApplicationContext) (ac); 14 aac.close();*/ 15 }
运行测试类:
说明spring容器对象一旦创建,那么bean对象就会创建。
b:将配置文件中bean元素上添加lazy-init="true"属性
1 <!-- 实例化ExampleBean对象 --> 2 <bean id="exampleBean" class="com.hlcui.dao.ExampleBean" 3 lazy-init="true" init-method="init" destroy-method="destroy" scope="singleton"></bean>
那么在运行测试方法时,并没有实例任何对象,说明延迟了实例bean对象。
c:去掉注释中的代码,再运行测试方法时
说明在使用到ExampleBean对象的时候才会实例化对象
如果在顶级元素beans上面添加属性default-lazy-init="true"时,那么默认在实例所有的bean
对象的时候都会延迟。
注:这里有点类似servlet容器,如果在web.xml中配置loadon-start-up时,那么在服务启动时就会创建
servlet对象,等待浏览器客户端的请求,如果不配置,那么只有当第一个请求发送过来的使用,才会创建
servlet对象,而且只会创建一个servlet对象。
<!-- 实例化ExampleBean对象 --><bean id="exampleBean" class="com.hlcui.dao.ExampleBean"init-method="init" destroy-method="destroy" scope="prototype"></bean>