您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java Spring中Bean的作用域及生命周期案例分析的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
原因:Bean的作用域默認(rèn)是單例模式的,也就是說所有?的使?的都是同?個(gè)對(duì)象!之前我們學(xué)單例模式的時(shí)候都知道,使?單例可以很?程度上提?性能,所以在 Spring 中Bean 的作?域默認(rèn)也是 singleton 單例模式。
@Component public class Users { @Bean public User user1(){ User user = new User(); user.setId(1); user.setName("Java"); return user; } }
@Component public class Bean1 { @Autowired private User user; public User getUser(){ System.out.println("Bean1對(duì)象未修改name之前 : "+user); user.setName("C++"); return user; } }
@Component public class Bean2 { @Autowired private User user; public User getUser(){ return user; } }
public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); Bean1 bean1 = context.getBean("bean1",Bean1.class); System.out.println(bean1.getUser()); Bean2 bean2 = context.getBean("bean2",Bean2.class); System.out.println(bean2.getUser()); } }
相同資源只創(chuàng)建一份,節(jié)省空間
不需要過多的創(chuàng)建和銷毀對(duì)象,執(zhí)行速度提高
作用域,一般理解為:限定程序中變量的可?范圍叫做作?域,或者說在源代碼中定義變量的某個(gè)區(qū)域就叫做作?域。
?Bea
的作?域是指Bean
在 Spring
整個(gè)框架中的某種?為模式,?如singleton
單例作?域,就表
示Bean
在整個(gè)Spring
中只有?份,它是全局共享的,那么當(dāng)其他?修改了這個(gè)值之后,那么另?個(gè)
?讀取到的就是被修改的值。
在Spring中,bean 的作用域被稱為是行為模式,因?yàn)樵赟pring看來,單例模式,就是一種行為,意味著在整個(gè)Spring中bean只能存在一份。
singleton:單例作?域
prototype:原型作?域(多例作?域)
request:請求作?域
session:會(huì)話作?域
application:全局作?域
websocket:HTTP WebSocket 作?域
后四種都是SpringMVC中限定使用的,因此現(xiàn)階段我們只學(xué)前兩個(gè)就行。
回到剛才的案例,Bean2希望獲取到的bean對(duì)象是未被修改的,我們就可以將單例模式修改為多例模式。
使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
使用@Scope("prototype")
ps
:當(dāng)執(zhí)行性到裝配Bean的屬性那一步時(shí),當(dāng)掃描到有屬性注入時(shí),會(huì)先停下類注入,優(yōu)先進(jìn)行屬性注入,因?yàn)楹竺娴姆椒赡軙?huì)用到該屬性。
所謂的生命周期指的是一個(gè)對(duì)象從誕生到銷毀的整個(gè)生命過程,我們把這個(gè)過程就叫做一個(gè)對(duì)象的生命周期。
Bean 的生命周期分為以下5大部分:
1.實(shí)例化 Bean(為 Bean 分配內(nèi)存空間)
2.設(shè)置屬性(Bean 注入和裝配)
3.Bean 初始化
實(shí)現(xiàn)了各種 Aware 通知的方法,如 BeanNameAware、BeanFactoryAware、 ApplicationContextAware 的接口方法,例如:Spring在初始化 bean,是需要給 bean 賦予 id(name)。而設(shè)置 beanName 成功的話,就會(huì)生成一個(gè) beadNameAware 通知;執(zhí)行 BeanPostProcessor 初始化前置方法(如果沒有重寫此方法,按照源碼操作);執(zhí)行 @PostConstruct 初始化方法,依賴注入操作之后被 執(zhí)行;執(zhí)行自己指定的 init-method 方法(如果有指定的話),是Spring中bean標(biāo)簽內(nèi)指定的方法;
這個(gè)初始化方法和上面一個(gè)用注解初始化的方法是兩個(gè)不同時(shí)期的產(chǎn)物,init是xml時(shí)代產(chǎn)物,@PostConstruct是注解時(shí)代產(chǎn)物。優(yōu)先級(jí):當(dāng)梁總方法同時(shí)存在時(shí),優(yōu)先執(zhí)行注解,再執(zhí)行init執(zhí)行 BeanPostProcessor 初始化后置方法(如果沒有重寫此方法,按照源碼操作)。
4.使用 Bean
5.銷毀 Bean銷毀容器的各種方法, 如 @PreDestroy、DisposableBean 接口方法、destroy-method。
@PreDestroy和destroy-method的關(guān)系和初始化方法的兩個(gè)關(guān)系差不多
優(yōu)先級(jí):@ProDestroy > 重寫的DisposableBean接口方法 > destroy-method
執(zhí)行流程圖如下:
ps:
實(shí)例化和初始化的區(qū)別:實(shí)例化
就是 分配內(nèi)存空間。初始化
,就是把我們一些參數(shù),方法的具體實(shí)現(xiàn)邏輯給加載進(jìn)去。
xml配置如下:
Bean
public class BeanLifeComponent implements BeanNameAware { @PostConstruct public void PostConstruct(){ System.out.println("執(zhí)行@PostConstruct"); } public void init(){ System.out.println("執(zhí)行bean-init-method"); } public void use(){ System.out.println("正在使用bean"); } @PreDestroy public void PreDestroy(){ System.out.println("執(zhí)行@PreDestroy"); } public void setBeanName(String s){ System.out.println("執(zhí)行了Aware通知"); } }
啟動(dòng)類
public class App2 { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); BeanLifeComponent beanLifeComponent = context.getBean(BeanLifeComponent.class); beanLifeComponent.use(); context.destroy(); } }
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" xmlns:content="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <content:component-scan base-package="com.beans"></content:component-scan> <bean id="1" class="com.beans.BeanLifeComponent" init-method="init"></bean> </beans>
@Controller public class TestUser { @Autowired private Test test; public TestUser(){ test.sayHi(); System.out.println("TestUser->調(diào)用構(gòu)造方法"); } }
如果這段代碼先執(zhí)行了初始化,也就是其構(gòu)造方法,會(huì)用到test對(duì)象,此時(shí)還沒有設(shè)置屬性,test就為null,會(huì)造成空指針異常。因此必須先設(shè)置屬性,在進(jìn)行初始化。
以上就是“Java Spring中Bean的作用域及生命周期案例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。