javascript
java xml接口实例化_Spring简介及xml配置
Java Web發(fā)展史
第一階段:JavaBean+Servlet+Jsp逐步發(fā)展
第二階段:面對(duì)EJB重量級(jí)框架帶來的種種麻煩
第三階段:SpringMVC/Struts+Spring+Hibernate/myBatis
第四階段:享受SpringBoot"約定大于配置"的種種樂趣,很多繁瑣的配置都變成了約定
第五階段:以Dubbo為代表的SOA為服務(wù)架構(gòu)體系(Dubbo是阿里創(chuàng)建的)
第六階段:比較前沿的技術(shù),SpringCloud 微服務(wù)架構(gòu)技術(shù)生態(tài)圈(基于SpringBoot,保證了開箱即用,需要什么SpringCloud都有)
IoC 控制反轉(zhuǎn)
不只是Spring的IoC,其他的框架也具有相同的IoC思想及應(yīng)用:
控制: 控制對(duì)象的創(chuàng)建及銷毀(生命周期)
反轉(zhuǎn):將對(duì)象的控制權(quán)交給IoC容器
IoC容器約定
①所有Bean的生命周期交由IoC容器管理
②所有被依賴的Bean通過構(gòu)造方法執(zhí)行注入
③被依賴的Bean需要優(yōu)先創(chuàng)建
Spring IoC容器使用方法
概述
通過Spring.xml文件實(shí)例化Bean.只要Spring.xml中配置了bean標(biāo)簽,則就會(huì)根據(jù)class創(chuàng)建這個(gè)bean的實(shí)例.
把一個(gè)java bean交給Spring管理步驟:
1、創(chuàng)建一個(gè)xml格式的配置文件
2、在xml文件中定義一個(gè)bean,給每個(gè)bean設(shè)定一個(gè)id
3、通過ApplicationContext獲取Spring上下文
ApplicationContext context = new ClassPathXmlApplicatioinContext("文件名.xml");
4、獲取bean
`Bean bean = context.getBeal("第一步中給bean的id",Bean.class);
1、通過構(gòu)造方法實(shí)例化Bean
步驟1:創(chuàng)建要實(shí)例化的類,并提供無參構(gòu)造方法。
public class Bean {
public Bean(){
System.out.println("Bean被創(chuàng)建了");
}
步驟2:spring.xml中配置
測(cè)試:
ApplicationContext context=new ClassPathXmlApplicationContext(spring.xml的路徑);
Bean bean=context.getBean("bean",Bean.class);
System.out.println(bean);
2、通過靜態(tài)工廠方法實(shí)例化Bean
通過Bean2的工廠的靜態(tài)方法實(shí)例化Bean.
步驟1:創(chuàng)建Bean2的工廠Bean2Factory類以及Bean2類,并且提供一個(gè)靜態(tài)、返回值類型為Bean2的方法,返回new Bean2()。
public class Bean2Factory {
public static Bean2 getBean2(){
return new Bean2();
}
}
public class Bean2 {
public Bean2(){
System.out.println("Bean2被創(chuàng)建了。");
}
步驟2:配置Spring.xml
測(cè)試:
ApplicationContext context=new ClassPathXmlApplicationContext("spring-ioc2.xml");
Bean2 bean=context.getBean("bean2factoryId",Bean2.class);
System.out.println(bean);
3、通過實(shí)例工廠方法實(shí)例化Bean
通過Bean3的工廠的實(shí)例方法實(shí)例化Bean.
步驟1:創(chuàng)建Bean3的工廠Bean3Factory類以及Bean3類,并且提供一個(gè)返回值類型為Bean3的方法,方法返回new Bean3()。
public class Bean3Factory {
public Bean3 getBean3(){
return new Bean3();
}
}
public class Bean3 {
public Bean3(){
System.out.println("Bean3被創(chuàng)建了。");
}
}
步驟2:配置Spring.xml
給bean取別名
有類Bean1,并且通過bean標(biāo)簽實(shí)例化Bean1,可以給Bean1的實(shí)例取多個(gè)名字。
方式一: bean標(biāo)簽里添加name屬性
方式二: 添加標(biāo)簽
依賴注入的方式
1.通過構(gòu)造方法注入Bean
簡(jiǎn)化寫法:
2.通過Set()方法注入Bean
3.集合類型注入Bean
4.注入null空值
5.注入內(nèi)部bean
Spring中Bean的作用域
1、Singleton作用域(單例模式)
通過Spring容器實(shí)現(xiàn)單例模式,具有局限性:保證在一個(gè)Spring上下文(ApplicationContext)是單例模式,多個(gè)AppliactionContext單例模式就失效了。
2、prototype作用域(多例模式)
如果一個(gè)的作用域?yàn)閜rototype,則該會(huì)被實(shí)例化多次,有多個(gè)Bean會(huì)被創(chuàng)建(每次向Spring上下文請(qǐng)求該Bean都會(huì)new一個(gè)新的實(shí)例)。
Bean1依賴Bean2,總結(jié)起來:
對(duì)于藍(lán)框中的情況,有時(shí)候我們需要單個(gè)Bean1,多個(gè)Bean2,就要用到方法注入.
方法注入
Bean2代碼修改:
Spring.xml修改:
這樣即使Bean1是單例模式,每次拿到Bean1都會(huì)是不同的Bean2實(shí)例.
3、Web環(huán)境作用域
request作用域、session作用域、application作用域、websocket作用域(使用較少).....
request:每次瀏覽器刷新都會(huì)實(shí)例化一個(gè)新的bean;
session:瀏覽器刷新不會(huì)實(shí)例化新的bean,更換瀏覽器則會(huì)實(shí)例化新的bean;
application:bean實(shí)例化之后就不會(huì)改變,更換瀏覽器也不會(huì)。
SpringWeb上下文環(huán)境
在web.xml中定義:
不使用DispatcherServlet:
以RequestController為例:
在spring.xml中添加:
request:每次瀏覽器刷新都會(huì)實(shí)例化一個(gè)新的bean;
session:瀏覽器刷新不會(huì)實(shí)例化新的bean,更換瀏覽器則會(huì)實(shí)例化新的bean;
application:bean實(shí)例化之后就不會(huì)改變,更換瀏覽器也不會(huì)。
4、自定義作用域
Spring內(nèi)置的自定義SimpleThreadScope作用域
以自定義雙例模式為例:
步驟1:實(shí)現(xiàn)Scope接口
(org.springframework.beans.factory.config.Scope)主要關(guān)注實(shí)現(xiàn)的get方法和remove方法。
get()方法:按照name參數(shù),按照我們自己定義的規(guī)則,去返回一個(gè)Bean,如果我們定義的規(guī)則里,Bean不存在,那么將通過objectFactory去創(chuàng)建一個(gè)Bean。
雙例模式:一個(gè)bean的Id對(duì)應(yīng)兩個(gè)實(shí)例,實(shí)現(xiàn)雙例模式,需要兩個(gè)Map集合,Map map1=new HashMap();Map map2=new HashMap();。
get()方法:
public Object get(String name, ObjectFactory> objectFactory) {
if(!map1.containsKey(name)){ //判斷map1是否包含名為name的Bean實(shí)例
Object o=objectFactory.getObject();//如果不存在則創(chuàng)建一個(gè)ObjectFactory規(guī)則Bean
map1.put(name, o); //并把這個(gè)Bean放入集合,并命名為name
return o;
}
if(!map2.containsKey(name)){ //map2同map1操作
Object o=objectFactory.getObject();
map2.put(name, o);
return o;
}
//如果map1和map2都包含這個(gè)Bean,也就是說Spring上下文通過Id獲取有兩個(gè)實(shí)例,則返回一個(gè)0或1
int i=new Random().nextInt(2);
if(i==0){
return map1.get(name);//如果是0,則返回對(duì)象1
}else{
return map2.get(name);//如果是0,則返回對(duì)象2
}
}
remove()方法:和get方法相反,按照name參數(shù),去移除一個(gè)Bean。
public Object remove(String name) {
if(map1.containsKey(name)){
Object o=map1.get(name);
map1.remove(name);
return o;
}
if(map2.containsKey(name)){
Object o=map2.get(name);
map2.remove(name);
return o;
}
return null; //說明沒拿到任何實(shí)例
}
步驟2: spring.xml配置
測(cè)試
@Test
public void testBean(){
ApplicationContext ac=new ClassPathXmlApplicationContext("spring-zidingyi.xml");
for(int i=0;i<10;i++){
Bean bean=ac.getBean(“myScope”", Bean.class);
System.out.println(bean);
}
}
補(bǔ)充:SimpleThreadScope
Spring提供的線程內(nèi)單例作用域:
同一線程中Spring上下文會(huì)分配同一實(shí)例
不同線程(Thread)中,則獲得不同實(shí)例。
srping配置:
測(cè)試代碼:
public void testBean(){
final ApplicationContext ac=new ClassPathXmlApplicationContext("spring-zidingyi.xml");
for(int i=0;i<10;i++){
new Thread(new Runnable(){
@Override
public void run() {
Bean bean=ac.getBean("bean11", Bean.class);
System.out.println(bean);
}
}).start();
}
}
}
默認(rèn)Scope(單例)Bean的懶加載
Spring容器會(huì)在創(chuàng)建容器時(shí)提前初始化Singleton作用域的bean,但是如果Bean被標(biāo)注了lazy-init=“true”,則該Bean只有在其被需要的時(shí)候才會(huì)被初始化。(只對(duì)singleton作用域的bean有效)
如
多個(gè)bean使用懶加載:
表示spring配置文件里所有bean都是懶加載模式。
使用場(chǎng)景:
如果某個(gè)Bean在程序整個(gè)運(yùn)行周期都可能不會(huì)被使用,那么可考慮設(shè)定該Bean為懶加載。
優(yōu)點(diǎn):盡可能的節(jié)省了資源。
缺點(diǎn):可能會(huì)導(dǎo)致某個(gè)操作相應(yīng)操作時(shí)間增加。
Bean初始化及銷毀
以singleton作用域?yàn)槔?假設(shè)有一個(gè)javaBean,該Bean的作用是連接數(shù)據(jù)庫,該Bean被創(chuàng)建之后,執(zhí)行數(shù)據(jù)庫連接操作.
Bean初始化
如果需要在Bean實(shí)例化時(shí)執(zhí)行一些邏輯,Spring提供了兩種方法:
方法1:bean標(biāo)簽里的init-method屬性,該值為Bean的某一方法,Spring實(shí)例化時(shí),會(huì)調(diào)用Bean的該方法。
方法2:讓Bean實(shí)現(xiàn)InitializingBean接口,Spring在實(shí)例化該Bean時(shí),檢測(cè)到Bean實(shí)現(xiàn)了該接口,就會(huì)調(diào)用該接口所定義的相應(yīng)方法。
Bean銷毀
如果需要在Bean銷毀之前執(zhí)行一些邏輯,有兩種方法。
方法1:bean標(biāo)簽里的destory-method屬性,該值為Bean的某一方法,Spring銷毀該Bean時(shí),會(huì)調(diào)用Bean的該方法。
方法2:讓Bean實(shí)現(xiàn)DisposableBean接口,Spring在銷毀該Bean時(shí),檢測(cè)到Bean實(shí)現(xiàn)了該接口,就會(huì)調(diào)用該接口所定義的相應(yīng)方法。
案例1:
通過bean標(biāo)簽的init-method和destory-method屬性來指定Bean初始化邏輯和銷毀邏輯。
代碼:
public class Bean {
public void onInit(){
System.out.println("Bean的初始化邏輯方法被執(zhí)行了");
}
public void onDestory(){
System.out.println("Bean的銷毀邏輯方法被執(zhí)行了");
}
}
spring.xml配置:
id="bean"
init-method="onInit"
destroy-method="onDestory"/>
測(cè)試代碼:
@Test
public void test(){
ApplicationContext ac=new ClassPathXmlApplicationContext("spring-initAnddestory.xml");
Bean bean=ac.getBean("bean", Bean.class);
System.out.println(bean);
}
結(jié)果:bean的銷毀方法沒執(zhí)行,因?yàn)楫?dāng)前是單例模式,所以Bean的初始化是在Spring上下文實(shí)例化完成的,Bean的銷毀是在Spring上下文的銷毀過程中執(zhí)行Bean的銷毀。(Spring上下文的銷毀定義到AbstractApplicationContext中)
改進(jìn):
@Test
public void test(){
AbstractApplicationContext ac=new ClassPathXmlApplicationContext("spring-initAnddestory.xml");
Bean bean=ac.getBean("bean", Bean.class);
System.out.println(bean);
ac.close();
}
注意:如果所有的Bean都有相同名稱的初始化方法和相同名稱的銷毀方法,可以在spring.xml中定義:
default-destory-method="onDestory"/>
案例2:
實(shí)現(xiàn)相應(yīng)接口,并實(shí)現(xiàn)相應(yīng)方法
代碼:
public class Bean implements InitializingBean,DisposableBean{
@Override
public void destroy() throws Exception {
System.out.println("Bean的銷毀邏輯方法被執(zhí)行了");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bean的初始化邏輯方法被執(zhí)行了");
}
}
spring.xml配置:
Bean屬性繼承
應(yīng)用場(chǎng)景
場(chǎng)景1:
ParentClass(屬性1,屬性2,屬性3,get和set方法)
子類1(屬性4,屬性5)
子類2(屬性6,屬性7)
場(chǎng)景2:
子類1和子類2沒有父類,而是有一些相同的屬性。
類1:(屬性1,屬性2,屬性3,屬性4,屬性5)
類2:(屬性1,屬性2,屬性3,屬性6,屬性7)
這兩個(gè)場(chǎng)景下,通過Spring注入類1和類2的所有屬性,一般如下:
abstract="true":設(shè)置標(biāo)簽只是定義性的,不會(huì)對(duì)它進(jìn)行實(shí)例化操作。
parent屬性:在Bean的子類bean標(biāo)簽添加,值為父類的Id。
場(chǎng)景1:
spring.xml配置:
場(chǎng)景2:
類1和類2不繼承某一父類,只是存在相同屬性。
spring.xml配置:
總結(jié)
以上是生活随笔為你收集整理的java xml接口实例化_Spring简介及xml配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php未定义要怎样做,php-Behat
- 下一篇: gradle idea java ssm