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