Spring框架中JavaBean的生命周期及单例模式与多列模式
- [1. Spring框架中JavaBean的管理过程](#1. Spring框架中JavaBean的管理过程)
-
- 1.1 #定义Bean
- [1.2 Bean的实例化](#1.2 Bean的实例化)
- [1.3 属性注入](#1.3 属性注入)
- [1.4 初始化方法](#1.4 初始化方法)
- [1.5 Bean的使用和引用](#1.5 Bean的使用和引用)
- [1.6 销毁方法](#1.6 销毁方法)
- [2. 单例模式与原型模式在JavaBean管理中的应用](#2. 单例模式与原型模式在JavaBean管理中的应用)
-
- 1.在Spring管理JavaBean的过程中,每个Bean都有一个生命周期,包括以下几个阶段:
- [2.1 单例模式与多列模式](#2.1 单例模式与多列模式)
- 2.在单例模式中,JavaBean是跟着spring上下文初始化的:
- 4.我们使用单例一定会初始化JavaBean吗
在使用Spring框架进行Java开发时,对于JavaBean的管理是一个重要而又常见的问题。同时,在JavaBean的管理中,单例模式和原型模式也是必须深入了解的概念。本文将带你全方位探讨Spring框架中JavaBean的管理过程,并深入拓展单例模式和原型模式在JavaBean管理中的应用。
1. Spring框架中JavaBean的管理过程
在Spring框架中,JavaBean的管理主要是通过IOC(Inversion of Control)容器实现的。IOC容器负责创建、管理和注入JavaBean对象,使得开发者能够更加专注于业务逻辑的实现。JavaBean的管理过程包括以下几个步骤:
1.1 #定义Bean
首先,我们需要在配置文件或者通过注解明确定义需要被Spring容器管理的JavaBean。定义Bean时,需要指定Bean的名称、类型、作用域以及其他属性信息。
1.2 Bean的实例化
当Spring容器启动时,会根据配置文件中的定义信息,实例化相应的Bean对象。通过反射机制和工厂模式,Spring容器会根据Bean的定义创建对应的JavaBean实例。
1.3 属性注入
在Bean实例化完成后,Spring容器会根据配置文件中的属性信息,将相应的值注入到Bean中。属性注入可以通过构造函数注入、Setter方法注入或字段注入等方式进行。
1.4 初始化方法
当属性注入完成后,Spring容器会调用Bean的初始化方法(如果有定义的话)。初始化方法可以由开发者自定义,在配置文件或注解中进行指定。在这个阶段,我们可以对Bean做一些额外的初始化操作,例如数据加载、资源分配等。
1.5 Bean的使用和引用
初始化完毕后,Bean就可以被其他对象引用和使用了。在应用程序运行过程中,我们可以随时通过Spring容器获取已经初始化的Bean,并调用其方法进行业务处理。
1.6 销毁方法
当应用程序关闭或者不再需要某个Bean时,Spring容器会调用Bean的销毁方法进行清理工作。开发者可以在配置文件或注解中指定销毁方法,以执行一些资源释放、连接关闭等操作。
2. 单例模式与原型模式在JavaBean管理中的应用
除了JavaBean的管理过程外,单例模式和原型模式也是在JavaBean管理中常见的设计模式。它们分别用于控制JavaBean对象的创建方式和作用域。
1.在Spring管理JavaBean的过程中,每个Bean都有一个生命周期,包括以下几个阶段:
2.1 单例模式与多列模式
1.单例模式保证一个类只有一个实例,并且提供一个全局访问点。在Spring框架中,单例模式广泛应用于Bean的管理中,默认情况下,Spring容器会将所有的Bean都注册为单例对象。这意味着每次从容器中获取Bean时,都会返回同一个实例。
1.在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)
singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。单例的优点在于可以节约内存,弊端在于会有变量污染。
prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。多例的优劣则与单例相反,不会有变量污染,但却非常消耗内存。
代码论证
ParamAction
java
package com.zking.beanlife;
import java.util.List;
public class ParamAction {
private int age;
private String name;
private List<String> hobby;
private int num = 1;
// private UserBiz userBiz = new UserBizImpl1();
public ParamAction() {
super();
}
public ParamAction(int age, String name, List<String> hobby) {
super();
this.age = age;
this.name = name;
this.hobby = hobby;
}
public void execute() {
// userBiz.upload();
// userBiz = new UserBizImpl2();
System.out.println("this.num=" + this.num++);
System.out.println(this.name);
System.out.println(this.age);
System.out.println(this.hobby);
}
}
demo
java
package com.zking.beanlife;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/*
* spring bean的生命週期
* spring bean的單例多例
*/
public class Demo2 {
// 体现单例与多例的区别
@Test
public void test1() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/sping-context.xml");
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
// System.out.println(p1==p2);
p1.execute();
p2.execute();
// 单例时,容器销毁instanceFactory对象也销毁;多例时,容器销毁对象不一定销毁;
applicationContext.close();
}
// 体现单例与多例的初始化的时间点 instanceFactory
@Test
public void test2() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/sping-context.xml");
}
// BeanFactory会初始化bean对象,但会根据不同的实现子类采取不同的初始化方式
// 默认情况下bean的初始化,单例模式立马会执行,但是此时XmlBeanFactory作为子类,单例模式下容器创建,bean依赖没有初始化,只有要获取使用bean对象才进行初始化
@Test
public void test3() {
// ClassPathXmlApplicationContext applicationContext = new
// ClassPathXmlApplicationContext("/spring-context.xml");
Resource resource = new ClassPathResource("/spring-context.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
// InstanceFactory i1 = (InstanceFactory) beanFactory.getBean("instanceFactory");
}
}
spring-context.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
default-autowire="byType"
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.xsd">
<bean class="com.zking.ioc.web.UserAction" id="userAction">
<!-- <property name="userService" ref="userService"></property>-->
<!--<constructor-arg name="uname" value="袁辉sb"></constructor-arg>-->
<!-- <constructor-arg name="age" value="11"></constructor-arg>-->
<!-- <constructor-arg name="hobby" >-->
<!-- <list>-->
<!-- <value>-->
<!-- 农村-->
<!-- </value>-->
<!-- <value>-->
<!-- 农村-->
<!-- </value>-->
<!-- <value>-->
<!-- 农村-->
<!-- </value>-->
<!-- </list>-->
<!-- </constructor-arg>-->
</bean>
<bean class="com.zking.ioc.web.GoodsAction" id="goodsAction">
<!-- <property name="userService" ref="userService"></property>-->
<!-- <property name="gname" value="雨伞"></property>-->
<!-- <property name="age" value="1"></property>-->
<!-- <property name="peoples" >-->
<!-- <list>-->
<!-- <value>男的</value>-->
<!-- <value>女的</value>-->
<!-- </list>-->
<!-- </property>-->
</bean>
<bean class="com.zking.ioc.impl.UserServiceImpl1" id="userService"></bean>
<bean class="com.zking.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>
<bean class="com.zking.aop.advice.MyMethodBeforeAdvice" id="methodBeforeAdvice"></bean>
<bean class="com.zking.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>
<bean class="com.zking.aop.advice.MyMethodInterceptor" id="methodInterceptor"></bean>
<bean class="com.zking.aop.advice.MyThrowsAdvice" id="myThrowsAdvice"></bean>
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="methodPointcutAdvisor">
<property name="advice" ref="myAfterReturningAdvice"></property>
<property name="pattern" value=".*buy"></property>
</bean>
<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
<property name="target" ref="bookBiz"></property>
<property name="proxyInterfaces">
<list>
<value>com.zking.aop.biz.IBookBiz</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>methodBeforeAdvice</value>
<!-- <value>myAfterReturningAdvice</value>-->
<value>methodPointcutAdvisor</value>
<value>methodInterceptor</value>
<value>myThrowsAdvice</value>
</list>
</property>
</bean>
<bean class="com.zking.beanlife.ParamAction" id="paramAction" scope="prototype">
<constructor-arg name="name" value="三丰"></constructor-arg>
<constructor-arg name="age" value="21"></constructor-arg>
<constructor-arg name="hobby">
<list>
<value>抽烟</value>
<value>烫头</value>
<value>大保健</value>
</list>
</constructor-arg>
</bean>
<bean id="instanceFactory" class="com.zking.beanlife.InstanceFactory"
scope="singleton" init-method="init" destroy-method="destroy"></bean>
</beans>
在单列模式下可以看到变量已经被污染从一变为2
然后我们吧spring-context.xml
文件变为多列
然后可以看到污染已经消失
2.在单例模式中,JavaBean是跟着spring上下文初始化的:
java
package com.zking.beanlife;
public class InstanceFactory {
public void init() {
System.out.println("初始化方法");
}
public void destroy() {
System.out.println("销毁方法");
}
public void service() {
System.out.println("业务方法");
}
}
4.我们使用单例一定会初始化JavaBean吗
BeanFactory会初始化bean对象,但会根据不同的实现子类采取不同的初始化方式,默认情况下bean的初始化,单例模式立马会执行,但是此时XmlBeanFactory作为子类,单例模式下容器创建,bean依赖没有初始化,只有要获取使用bean对象才进行初始化。