Spring框架 之 Spring容器初始化

Spring容器(Core Container)支持三種配置方式

一、基于XML配置文件:在XML文件中使用Spring命名空間所支持的標(biāo)簽與屬性來配置Spring容器。

在XML配置文件中,我們使用<bean>標(biāo)簽來制定創(chuàng)建對象的類,并根據(jù)XML配置文件完成Springr的初始化。例如:    

<pre class="html" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">

<!-- 使用bean標(biāo)簽創(chuàng)建實例  
    1.id:該實例在容器中的名稱,容器中唯一  
    2.class:實例的類路徑  
    3.scope:作用域  
    4.init-method:初始化方法的名稱,在創(chuàng)建該實例后,會Spring容器會調(diào)用該方法  
    5.destroy-method:在Spring容器釋放資源時,銷毀該實例前會調(diào)用此方法  
    6.lazy-init:是否開啟懶加載,bean標(biāo)簽中的懶加載優(yōu)先級高于beans標(biāo)簽中的default-lazy-init屬性  
 -->  
<bean   
id="test"   

<span style="white-space:pre;"> </span>class="beans.Test"
<span style="white-space:pre;"> </span>scope="singleton"
<span style="white-space:pre;"> </span>init-method="doInit"
<span style="white-space:pre;"> </span>destroy-method="doDestroy"
<span style="white-space:pre;"> </span>lazy-init="false"/>

</beans> </pre>

獲取對象的方式:

<pre class="java" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">package beans;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
public static void main(String[] args) {
//通過XML配置文件初始化Spring容器,“test.xml”為配置文件的文件名與路徑
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("test.xml");
//通過上下文對象獲取類的實例,“test”為bean對象的id
Test test=ctx.getBean("test", Test.class);
//使用實例
test.testMethod();
//釋放資源
ctx.close();
}
}</pre>

//構(gòu)造方法

public Test() {super();System.out.println("Test.Test()");}

//初始化方法

public void doInit() {System.out.println("Test.doInit()");}

//釋放資源的方法

public void doDestroy() {System.out.println("Test.doDestroy()");}

//業(yè)務(wù)方法

public void testMethod() {System.out.println("Test.testMethod()");}}

輸出結(jié)果:

image

二、基于注解:使用Spring提供的注解修飾特定的類,初始化Spring容器時基于注解創(chuàng)建對象完成初始化。

在Spring中,可以使用@Service(業(yè)務(wù)層對象)、@Controller(控制層對象)、@Repository(持久層對象)、@Component(其他一般類)注解來修飾要創(chuàng)建對象的類,并使用<centext:component-scan>標(biāo)簽或者@ComponentScan注解來指明要創(chuàng)建實例的包的路徑(base-package或basePackages)。例如:

<pre class="java" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">@Service//表示這是一個業(yè)務(wù)層對象
public class Test {
...
} </pre>

獲取對象的方式:

可使用純注解的方式

<pre class="java" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">package beans;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;

//開啟掃描包創(chuàng)建實例
@ComponentScan("beans")
//表示該類是一個業(yè)務(wù)層類
@Service(value="test")
public class Test {

public static void main(String[] args) {  
    //通過全注解的形式創(chuàng)建對象,需將被@ComponentScan注解修飾的類的Class對象作為參數(shù)傳遞給Spring容器上下文對象  
    AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(Test.class);  
    //通過上下文對象獲取類的實例,“test”為bean對象的id  
    Test test=ctx.getBean("test", Test.class);  
    //使用實例  
    test.testMethod();  
    //釋放資源  
    ctx.close();  
}  

public Test() {  
    super();  
    System.out.println("Test.Test()");  
}  
//定義初始化方法  
@PostConstruct  
public void doInit() {  
    System.out.println("Test.doInit()");  
}  
//定義銷毀方法  
@PreDestroy  
public void doDestroy() {  
    System.out.println("Test.doDestroy()");  
}  
//業(yè)務(wù)方法  
public void testMethod() {  
    System.out.println("Test.testMethod()");  
}  

} </pre>

輸出結(jié)果與基于XML配置文件的方式相同。

也可以省去@ComponentScan注解,在XML文件中添加<context:component-scan>標(biāo)簽開啟包掃描并指定包路徑,使用上文提到的@Service、@Component等注解修飾要交由Spring容器創(chuàng)建實例的類,使用ClassPathXmlApplicationContext類加載XML配置文件并獲取實例。

基于XML文件和基于注解是最常用的兩種配置方式,并且可以混合使用。不過需要注意的是,如果XML文件中的bean對象與通過注解創(chuàng)建的對象的id或name相同的話,將只會創(chuàng)建一個對象。

test.xml文件內(nèi)容:

<pre class="java" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">...

<context:component-scan base-package="beans"/>

<bean   
id="test"   
class="beans.Test"   
scope="singleton"   
init-method="doInit"   
destroy-method="doDestroy"   
lazy-init="false"/>  

... </pre>

Test類內(nèi)容:

<pre class="java" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">package beans;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

@Service(value="test")
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("test.xml");
Test test=ctx.getBean("test", Test.class);
test.testMethod();
ctx.close();
}
public Test() {
super();
System.out.println("Test.Test()");
}
@PostConstruct
public void doInit() {
System.out.println("Test.doInit()");
}
@PreDestroy
public void doDestroy() {
System.out.println("Test.doDestroy()");
}
public void testMethod() {
System.out.println("Test.testMethod()");
}
} </pre>

輸出結(jié)果:
image
結(jié)果顯示Test類構(gòu)造器只執(zhí)行了一次,證明雖然在兩處都配置了創(chuàng)建實例的語句,但是只創(chuàng)建了一個實例。

三、基于JAVA配置:使用 @Configuration 和 @Bean 注解配合完成Spring容器的配置。

我們也可以使用@Configuration注解修飾一個類,并且在該類中使用@Bean注解修飾該類的方法,被修飾的方法執(zhí)行后會返回一個對象,該對象在Spring容器中的id為方法名。例如:

<pre class="java" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">@Configuration
public class TestConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
} </pre>

基于JAVA的配置方式與前兩種方式類似,相當(dāng)于把XML文件寫在@Configuration修飾的配置類中,在配置類中使用@Bean注解代替XML文件中的<bean>標(biāo)簽。@Bean注解中有各種屬性,類似于<bean>標(biāo)簽中的屬性,不過作用域與延遲加載要使用單獨的注解@Scope或@Lazy來聲明。

<pre class="java" style="box-sizing: border-box; margin: 0px 0px 24px; padding: 0px 16px; overflow-x: auto; background-color: rgb(240, 240, 240); font-family: Consolas, Inconsolata, Courier, monospace; font-size: 12px; line-height: 20px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">package beans;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

//開啟掃描包創(chuàng)建實例
@ComponentScan("beans")
//基于JAVA配置創(chuàng)建對象
@Configuration
public class Test {

public static void main(String[] args) {  
    //通過全注解的形式創(chuàng)建對象,需將被@ComponentScan注解修飾的類的Class對象作為參數(shù)傳遞給Spring容器上下文對象  
    AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(Test.class);  
    //通過上下文對象獲取類的實例,“test”為bean對象的id  
    Test test=ctx.getBean("test00", Test.class);  
    test=ctx.getBean("test01", Test.class);  
    //使用實例  
    test.testMethod();  
    //釋放資源  
    ctx.close();  
}  

@Bean(value={"test00","test01"},initMethod="doInit",destroyMethod="doDestroy")  
@Lazy(false)  
@Scope(value="singleton")  
public Test test() {  
    return new Test();  
}  

public Test() {  
    super();  
    System.out.println("Test.Test()");  
}  
//定義初始化方法  
public void doInit() {  
    System.out.println("Test.doInit()");  
}  
//定義銷毀方法  
public void doDestroy() {  
    System.out.println("Test.doDestroy()");  
}  
//業(yè)務(wù)方法  
public void testMethod() {  
    System.out.println("Test.testMethod()");  
}  

} </pre>

輸出結(jié)果與前兩種一致,不過需要注意的是,在根據(jù)@Bean修飾的方法創(chuàng)建對象之前,會先為@Configuration修飾的類創(chuàng)建實例,在本例控制臺輸出中,會有兩個“Test.Test()”。

基于JAVA的配置方式可以通過前兩種的任意一種方式初始化Spring并且獲取對象。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容