一、spring框架概念
spring是众多开源java项目中的一员,基于分层的javaEE应用一站式轻量级开源框架,主要核心是Ioc(控制反转/依赖注入) 与Aop(面向切面)两大技术,实现项目在开发过程中的轻松解耦,并极大的提高项目的开发效率。
在项目中引入spring立即可以带来下面的好处 降低组件之间的耦合度,实现软件各层之间的解耦。可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务.也不需处理复杂的事务传播。 容器提供单例模式支持,开发人员不再需要自己编写实现代码。 容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。
二、spring的七大模块
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。
- 核心容器Spring Core: 核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 思想将应用程序的配置和依赖性规范与实际的应用程序代码分开。
- Spring 上下文Spring Context:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
- Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,就可以将声明性事务管理集成到应用程序中。
- Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
- Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
- Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
- Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
思考:Bean 是如何被实例化的?---工厂模式(简单模拟实现工厂模式)
简单工厂模式:抽象产品角色,具体产品角色,工厂角色
三、Spring Ioc(控制反转/依赖注入)(Dependency Injection 即DI)
原先我们是通过手动的方式实例化new我们的对象,
现在将原先的过程交给我们web容器(spring)来进行创建,这个过程叫做控制反转、依赖注入。
目的:实现解耦
四、Spring Ioc实例化bean对象的三种方式
1、构造器的方式实例化bean对象
2、静态工厂方法方式实例化bean(了解即可)
特点:
I.要有该工厂类及工厂方法
II.工厂方法为静态的
3、 实例化工厂方式创建bean(了解即可)
相比较静态工厂实现
I.工厂方法为非静态方法
II.需要配置工厂bean,并在业务bean中配置factory-bean,factory-method属性
spring三种实例化bean的方式比较
方式一:通过bean的缺省构造函数创建,当各个bean的业务逻辑相互比较独立的时候或者和外界关联较少的时候可以使用。
方式二:利用静态factory方法创建,可以统一管理各个bean的创建,如各个bean在创建之前需要相同的初始化处理,则可用这个factory方法险进行统一的处理等等。
方式三:利用实例化factory方法创建,即将factory方法也作为了业务bean来控制,1可用于集成其他框架的bean创建管理方法,2能够使bean和factory的角色互换。
开发中项目一般使用一种方式实例化bean,采用第一种方式最好,交给spring托管,使用时直接拿来使用即可。另外两种了解即可
五、Spring Ioc 4种注入方式
1)Set注入
xml配置(同时 spring 也提供了对于基本数据类型的set注入方式)
1 <!-- 2 id:名称唯一,一般是类名的全称,第一个首字母小写 3 class:bean的全限命名 4 --> 5 <!-- set注入 --> 6 <bean id="userService" class="com.wisezone.service.UserService"> 7 <property name="userDao" ref="userDao"></property> 8 <property name="age" value="23"></property> 9 <property name="sex" value="1"></property> 10 <property name="name" value="张三"></property> 11 </bean> 12 13 <bean id="userDao" class="com.wisezone.dao.UserDao"></bean>
java类
1 package com.wisezone.dao; 2 3 public class UserDao { 4 5 public void save(){ 6 System.out.println("保存用户记录!"); 7 } 8 }
1 package com.wisezone.service; 2 3 import com.wisezone.dao.UserDao; 4 5 public class UserService { 6 7 private UserDao userDao; 8 9 private Integer age;//年龄 10 11 private boolean sex;//性别 12 13 private String name;//姓名 14 15 16 public void setAge(Integer age) { 17 this.age = age; 18 } 19 20 public void setSex(boolean sex) { 21 this.sex = sex; 22 } 23 24 public void setName(String name) { 25 this.name = name; 26 } 27 28 public void setUserDao(UserDao userDao) { 29 this.userDao = userDao; 30 } 31 32 public String save(){ 33 System.out.println("age:"+age+"--->sex:"+sex+"--->name:"+name); 34 userDao.save(); 35 return "hello spring"; 36 } 37 }
1 package com.wisezone.test; 2 3 import static org.junit.Assert.*; 4 5 import org.junit.Test; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 import org.springframework.context.support.FileSystemXmlApplicationContext; 9 10 import com.wisezone.service.UserService; 11 12 public class TestUserService { 13 14 @Test 15 public void test() { 16 /** 17 * 1、启动容器 18 * 2、获取bean 19 * 3、调用bean方法,打印信息 20 */ 21 //1、传入xml 启动spring 容器 22 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 23 24 //2、获取bean 25 UserService userService = (UserService) ac.getBean("userService"); 26 27 //3、调用bean方法,打印信息 28 System.out.println(userService.save()); 29 } 30 31 }
结果:
2)构造器注入
xml配置(也提供对于基本数据类型的构造器注入值得方式)
1 <!-- 构造器注入 --> 2 <!-- <bean id="userService2" class="com.wisezone.service.UserService2"> 3 <constructor-arg name="userDao" ref="userDao"></constructor-arg> 4 <constructor-arg name="userName" value="admin"></constructor-arg> 5 <constructor-arg name="addr" value="上海上海"></constructor-arg> 6 </bean> --> 7 8 <!-- 以index下标同样可以实现赋值 --> 9 <bean id="userService2" class="com.wisezone.service.UserService2"> 10 <constructor-arg index="0" ref="userDao"></constructor-arg> 11 <constructor-arg index="1" value="admin"></constructor-arg> 12 <constructor-arg index="2" value="上海上海"></constructor-arg> 13 </bean> 14 15 <bean id="userDao" class="com.wisezone.dao.UserDao"></bean>
java类
1 package com.wisezone.service; 2 3 import com.wisezone.dao.UserDao; 4 5 public class UserService2 { 6 7 private UserDao userDao; 8 9 private String userName; 10 11 private String addr; 12 13 14 //带参构造 15 public UserService2(UserDao userDao,String userName,String addr) { 16 super(); 17 this.userDao = userDao; 18 this.userName = userName; 19 this.addr = addr; 20 } 21 22 23 public String save(){ 24 System.out.println("userName:"+userName+"---->>>addr:"+addr); 25 userDao.save(); 26 return "hello spring"; 27 } 28 }
1 package com.wisezone.test; 2 3 import static org.junit.Assert.*; 4 5 import org.junit.Test; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 import org.springframework.context.support.FileSystemXmlApplicationContext; 9 10 import com.wisezone.service.UserService; 11 import com.wisezone.service.UserService2; 12 13 public class TestUserService2 { 14 15 @Test 16 public void test() { 17 /** 18 * 1、启动容器 19 * 2、获取bean 20 * 3、调用bean方法,打印信息 21 */ 22 //1、传入xml 启动spring 容器 23 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 24 25 //2、获取bean 26 UserService2 userService2 = (UserService2) ac.getBean("userService2"); 27 28 //3、调用bean方法,打印信息 29 System.out.println(userService2.save()); 30 } 31 32 }
结果:
3)静态工厂注入
1 <!-- 2 id:名称唯一,一般是类名的全称,第一个首字母小写 3 class:bean的全限命名 4 --> 5 <!-- set注入 --> 6 <bean id="userService" class="com.wisezone.service.UserService"> 7 <property name="userDao" ref="staticFactory"></property> 8 </bean> 9 10 <!-- 静态工厂注入 --> 11 <bean id="staticFactory" class="com.wisezone.factory.StaticFactory" factory-method="getUserDao"> 12 </bean>
java类
1 package com.wisezone.dao; 2 3 public class UserDao { 4 5 public void save(){ 6 System.out.println("保存用户记录!"); 7 } 8 }
1 package com.wisezone.factory; 2 3 import com.wisezone.dao.UserDao; 4 import com.wisezone.service.UserService; 5 6 /** 7 * 静态工厂实列化Bean 8 * @author 王东海 9 * @2017年4月27日 10 */ 11 public class StaticFactory { 12 13 public static UserService getUserService(){ 14 15 return new UserService(); 16 } 17 18 public static UserDao getUserDao(){ 19 20 return new UserDao(); 21 } 22 }
1 package com.wisezone.service; 2 3 import com.wisezone.dao.UserDao; 4 5 public class UserService { 6 7 private UserDao userDao; 8 9 10 public void setUserDao(UserDao userDao) { 11 this.userDao = userDao; 12 } 13 14 public String save(){ 15 userDao.save(); 16 return "这是一个spring学习的开始。。。静态工厂注入"; 17 } 18 }
1 package com.wisezone.test; 2 3 import static org.junit.Assert.*; 4 5 import org.junit.Test; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 import org.springframework.context.support.FileSystemXmlApplicationContext; 9 10 import com.wisezone.service.UserService; 11 12 public class TestUserService { 13 14 @Test 15 public void test() { 16 /** 17 * 1、启动容器 18 * 2、获取bean 19 * 3、调用bean方法,打印信息 20 */ 21 //1、传入xml 启动spring 容器 22 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 23 24 //2、获取bean 25 UserService userService = (UserService) ac.getBean("userService"); 26 27 //3、调用bean方法,打印信息 28 System.out.println(userService.save()); 29 } 30 31 }
结果:
4)实例化工厂注入
1 <!-- 2 id:名称唯一,一般是类名的全称,第一个首字母小写 3 class:bean的全限命名 4 --> 5 <!-- 实例化工厂注入 --> 6 <bean id="instanceFactory" class="com.wisezone.factory.InstanceFactory"></bean> 7 8 <bean id="userDao" factory-bean="instanceFactory" factory-method="getUserDao"></bean> 9 <!-- set注入 --> 10 <bean id="userService" class="com.wisezone.service.UserService"> 11 <property name="userDao" ref="userDao"></property> 12 </bean>
java类
1 package com.wisezone.dao; 2 3 public class UserDao { 4 5 public void save(){ 6 System.out.println("保存用户记录!"); 7 } 8 }
1 package com.wisezone.factory; 2 import com.wisezone.dao.UserDao; 3 import com.wisezone.service.UserService; 4 /** 5 * 实列化工厂 6 * @author 王东海 7 * @2017年4月27日 8 */ 9 public class InstanceFactory { 10 11 public UserService getUserService() 12 { 13 return new UserService(); 14 } 15 16 public UserDao getUserDao(){ 17 18 return new UserDao(); 19 } 20 21 }
1 package com.wisezone.service; 2 3 import com.wisezone.dao.UserDao; 4 5 public class UserService { 6 7 private UserDao userDao; 8 9 10 public void setUserDao(UserDao userDao) { 11 this.userDao = userDao; 12 } 13 14 public String save(){ 15 userDao.save(); 16 return "spring实列化工厂注入测试。。。。"; 17 } 18 }
1 package com.wisezone.test; 2 3 import static org.junit.Assert.*; 4 5 import org.junit.Test; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 import org.springframework.context.support.FileSystemXmlApplicationContext; 9 10 import com.wisezone.service.UserService; 11 12 public class TestUserService { 13 14 @Test 15 public void test() { 16 /** 17 * 1、启动容器 18 * 2、获取bean 19 * 3、调用bean方法,打印信息 20 */ 21 //1、传入xml 启动spring 容器 22 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 23 24 //2、获取bean 25 UserService userService = (UserService) ac.getBean("userService"); 26 27 //3、调用bean方法,打印信息 28 System.out.println(userService.save()); 29 } 30 31 }
结果:
六、Ioc集合类型属性注入(了解)
1)list集合注入
1 <property name="list"> 2 <list> 3 <value>java01</value> 4 <value>java02</value> 5 <value>java03</value> 6 <value>java04</value> 7 </list> 8 </property>
结果:
2)set集合注入
1 <property name="set"> 2 <set> 3 <value>10</value> 4 <value>20</value> 5 <value>30</value> 6 <value>40</value> 7 <value>50</value> 8 </set> 9 </property>
3)map类型属性注入
1 <property name="map"> 2 <map> 3 <entry> 4 <key> 5 <value>a</value> <!-- key值 --> 6 </key> 7 <value>hellojava</value> <!-- key对应value值 --> 8 </entry> 9 <entry> 10 <key> 11 <value>b</value> <!-- key值 --> 12 </key> 13 <value>helloworld</value> <!-- key对应value值 --> 14 </entry> 15 </map> 16 </property>
4)properties属性注入
1 <property name="properties"> 2 <props> 3 <prop key="a">test01</prop> 4 <prop key="b">test02</prop> 5 <prop key="c">test03</prop> 6 <prop key="d">test04</prop> 7 </props> 8 </property>
-----------------------------------------总代码----------------------------------------------------------
1 package com.wisezone.service; 2 3 import java.util.List; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 import java.util.Properties; 7 import java.util.Set; 8 9 10 public class UserService2 { 11 12 //1、list集合注入 13 private List<String> list; 14 15 //2、set集合注入 16 private Set<Double> set; 17 18 //3、map类型属性注入 19 private Map<String, String> map; 20 21 //4、Properties属性注入 22 private Properties properties; 23 24 25 public void setList(List<String> list) { 26 this.list = list; 27 } 28 29 public void setSet(Set<Double> set) { 30 this.set = set; 31 } 32 33 public void setMap(Map<String, String> map) { 34 this.map = map; 35 } 36 37 public void setProperties(Properties properties) { 38 this.properties = properties; 39 } 40 41 public void pointList(){ 42 for(String str:list){ 43 System.out.println(str); 44 } 45 } 46 47 public void pointSet(){ 48 for(Double temp:set){ 49 System.out.println(temp); 50 } 51 } 52 53 public void pointMap(){ 54 Set<Entry<String, String>> set = map.entrySet(); 55 for(Entry<String, String> entry:set){ 56 System.out.println(entry.getKey()+"----"+entry.getValue()); 57 } 58 } 59 60 61 public void pointProperties(){ 62 Set<Entry<Object, Object>> set = properties.entrySet(); 63 for(Entry<Object, Object> entry:set){ 64 System.out.println(entry.getKey()+"-----"+entry.getValue()); 65 } 66 } 67 68 }
1 package com.wisezone.test; 2 3 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 import com.wisezone.service.UserService2; 9 10 11 public class TestUserService2 { 12 13 @Test 14 public void test() { 15 /** 16 * 1、启动容器 17 * 2、获取bean 18 * 3、调用bean方法,打印信息 19 */ 20 //1、传入xml 启动spring 容器 21 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 22 23 //2、获取bean 24 UserService2 userService2 = (UserService2) ac.getBean("userService2"); 25 26 //list集合注入结果 27 // userService2.pointList(); 28 29 //set集合注入结果 30 // userService2.pointSet(); 31 32 //map类型属性注入结果 33 // userService2.pointMap(); 34 35 //pointProperties属性注入结果 36 userService2.pointProperties(); 37 38 39 } 40 41 }
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 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <!-- 8 id:名称唯一,一般是类名的全称,第一个首字母小写 9 class:bean的全限命名 10 --> 11 <bean id="userService2" class="com.wisezone.service.UserService2"> 12 <property name="list"> 13 <list> 14 <value>java01</value> 15 <value>java02</value> 16 <value>java03</value> 17 <value>java04</value> 18 </list> 19 </property> 20 21 <property name="set"> 22 <set> 23 <value>10</value> 24 <value>20</value> 25 <value>30</value> 26 <value>40</value> 27 <value>50</value> 28 </set> 29 </property> 30 31 <property name="map"> 32 <map> 33 <entry> 34 <key> 35 <value>a</value> <!-- key值 --> 36 </key> 37 <value>hellojava</value> <!-- key对应value值 --> 38 </entry> 39 <entry> 40 <key> 41 <value>b</value> <!-- key值 --> 42 </key> 43 <value>helloworld</value> <!-- key对应value值 --> 44 </entry> 45 </map> 46 </property> 47 48 <property name="properties"> 49 <props> 50 <prop key="a">test01</prop> 51 <prop key="b">test02</prop> 52 <prop key="c">test03</prop> 53 <prop key="d">test04</prop> 54 </props> 55 </property> 56 57 </bean> 58 </beans>
七、注解方式实现注入bean
对于bean的注入,除了使用xml 配置以外,注解的配置简化开发的速度,使程序看上去更简洁。对于注解的解释,spring对于注解有专门的解释器,对定义的注解进行解析,实现对应bean对象的注入,反射技术实现。
加入Aop jar包 spring-aop-4.3.2.RELEASE.jar
Xml 配置: 加入context命名空间 和xsd地址 并添加
<context:annotation-config/> 配置
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 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 <context:annotation-config/> 10 </beans>
对于bean的注入常用注解类型
@Autowired 属性字段或set方法上
@Resource 属性字段上或set方法上
区别:
@Autowired 默认按bean 的类型匹配 可以修改 按名称匹配 和@Qualifier配合使用
@Resource 默认按名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行匹配注入,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
推荐使用@Resource 注解是属于J2EE的,减少了与spring的耦合。
代码演示:
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" xmlns:context="http://www.springframework.org/schema/context" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context 7 http://www.springframework.org/schema/context/spring-context.xsd"> 8 9 <context:annotation-config /> 10 11 <bean id="userService" class="com.wisezone.service.UserService"> 12 </bean> 13 14 <bean id="userDao" class="com.wisezone.dao.UserDao"></bean> 15 16 </beans>
1 package com.wisezone.service; 2 3 import javax.annotation.Resource; 4 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.beans.factory.annotation.Qualifier; 7 8 import com.wisezone.dao.UserDao; 9 10 public class UserService { 11 12 /** 13 * 默认按照属性名称注入,如果没有找到对应名称,按照类型注入class 14 * 反射 set 15 */ 16 /*@Resource 17 private UserDao userDao;*/ 18 19 /** 20 * 默认按照类型 注入 21 */ 22 @Autowired 23 @Qualifier("userDao") 24 private UserDao userDao; 25 26 public String save(){ 27 userDao.save(); 28 return "hello spring"; 29 } 30 }
1 package com.wisezone.test; 2 3 import static org.junit.Assert.*; 4 5 import org.junit.Test; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 import org.springframework.context.support.FileSystemXmlApplicationContext; 9 10 import com.wisezone.service.UserService; 11 12 public class TestUserService { 13 14 @Test 15 public void test() { 16 /** 17 * 1、启动容器 18 * 2、获取bean 19 * 3、调用bean方法,打印信息 20 */ 21 //1、传入xml 启动spring 容器 22 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 23 24 //2、获取bean 25 UserService userService = (UserService) ac.getBean("userService"); 26 27 //3、调用bean方法,打印信息 28 System.out.println(userService.save()); 29 } 30 31 }
结果:
八、 Spring Ioc容器自动扫描管理bean
实际的开发中,bean的数量非常多,采用手动配置bean的方式已无法满足生产需要,spring这时候同样提供了扫描的方式,对扫描到的bean对象统一进行管理,简化开发配置,提高开发效率。
不需要再配置
同时对于被spring 管理的bean 类的定义上需要加入对应的注解定义
开发中建议(开发中的一种约定)
Dao 层:@Repository
Service层:@Service
视图控制层:@Controller
如果对于开发的类实在不明确到底属于哪个层,可以使用@Component注解定义。
九、 Bean的作用域问题
默认情况下,我们从spring容器中拿到的对象均是单例的,对于bean的作用域类型如下:
1、 singleton 作用域
默认情况下,被管理的bean只会IOC容器中存在一个实例,对于所有获取该Bean的操作Spring容器将只返回同一个Bean。
什么类型的对象适合作为单例对象来使用呢? service,dao,action等
一般来说对于无状态或状态不可改变的 对象适合使用单例模式(什么是无状态或状态不可改变)
实际上对象状态的变化往往均是由于属性值得变化而引起的,比如user类 年龄属性会有变化 属性年龄的变化一般会引起user对象状态的变化。对于我们的程序来说,无状态对象 没有实例变量的存在,保证了线程的安全性,service 层业务对象即是无状态对象。线程安全的。
prototype 作用域
通过scope=” prototype” 设置bean的类型 ,每次向Spring容器请求获取Bean都返回一个全新的Bean,相对于“singleton”来说就是不缓存Bean,每次都是一个根据Bean定义创建的全新Bean。
2、 Web应用中的作用域(request、session、globalsession)
十、Bean的生命周期
1、Bean的定义
对比已经学过的servlet 生命周期(容器启动装载并实例化servlet类,初始化servlet,调用service方法,销毁servlet)。
同样对于spring容器管理的bean也存在生命周期的概念
在Spring中,Bean的生命周期包括Bean的定义、初始化、使用和销毁4个阶段
在Spring中,通常是通过配置文档的方式来定义Bean的。在一个配置文档中,可以定义多个Bean。
2、Bean的初始化
Spring bean 初始化有两种方式:
I.在配置文档中通过指定 init-method 属性来完成。
II.实现org.springframework.beans.factory.InitializingBean接口。
Bean对象实例化过程是在spring容器初始化时被实例化的,但也不是不可改变的,可以通过 lazy-init=”true” 属性延迟bean对象的初始化操作,此时再调用getbean 方法时才会进行bean的初始化操作
3、Bean的使用
I.使用BeanFactory
II.使用ApplicationContext
4、Bean的销毁
实现销毁方式(spring容器会维护bean对象的管理,可以指定bean对象的销毁所要执行的方法)
通过AbstractApplicationContext 对象,调用其close方法实现bean的销毁过程。
1 /** 2 * 测试Bean的销毁过程 3 * void 4 */ 5 @Test 6 public void test02() { 7 /** 8 * 1、启动容器 9 * 2、获取bean 10 * 3、调用bean方法,打印信息 11 */ 12 //1、传入xml 启动spring 容器 13 AbstractApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 14 15 //2、获取bean 16 UserService userService = (UserService) ac.getBean("userService"); 17 18 //3、调用方法(怎么判断单例的两个结果是否一样,只要打印它的地址就可以了) 19 System.out.println(userService); 20 21 //关闭 22 ac.close(); 23 }
结果: