Spring框架——關於IOC容器和註解的36個小實驗

實驗1:經過IOC容器建立對象,併爲屬性賦值★java

<bean id="page"  class="com.neuedu.Bean.Page">

<property name="fontSize" value="大寫"></property>

<property name="fontNum" value="12"></property>

</bean>

 

ApplicationContext iocContainer = new ClassPathXmlApplicationContext("applicationContext.xml");

Page bean2 = (Page)iocContainer.getBean("page");

 

實驗2:根據bean的類型從IOC容器中獲取bean的實例★mysql

<bean id="page"  class="com.neuedu.Bean.Page">

<property name="fontSize" value="大寫"></property>

<property name="fontNum" value="12"></property>

</bean>

 

ApplicationContext iocContainer = new ClassPathXmlApplicationContext("applicationContext.xml");

Page bean2 = iocContainer.getBean(Page.class);

  

 

實驗3:經過構造器爲bean的屬性賦值spring

<bean id="Book" class="com.neuedu.Bean.Book">

<!-- 如下爲給帶參構造器傳送參數 -->

<constructor-arg value="123" ></constructor-arg>

<constructor-arg value="456" ></constructor-arg>

<constructor-arg value="789" ></constructor-arg>

</bean>

  

 

實驗4:經過index屬性指定參數的位置sql

<bean id="Book" class="com.neuedu.Bean.Book">

<property name="num" value="123"></property>

<constructor-arg value="123" index="0"></constructor-arg>

<constructor-arg value="123" index="1"></constructor-arg>

<constructor-arg value="123" index="2"></constructor-arg>

</bean>

  

 

實驗5:經過類型不一樣區分重載的構造器數據庫

<bean id="page"  class="com.neuedu.Bean.Page">

<constructor-arg value="123" type="int"></constructor-arg>

<constructor-arg value="456" type="String"></constructor-arg>

</bean>

  

 

實驗6:經過p名稱空間爲bean賦值session

<bean id="Book2"  parent="Book"

p:num="254"

 />

  

實驗14:給bean的級聯屬性賦值mvc

<bean id="page"  class="com.neuedu.Bean.Page">

<constructor-arg value="123" type="int"></constructor-arg>

<constructor-arg value="456" type="String"></constructor-arg>

</bean>

<bean id="Book" class="com.neuedu.Bean.Book">

<property name="page" ref="page"></property>

</bean>

  

 

實驗21:測試bean的做用域,分別建立單實例和多實例的beanapp

<bean id="page" scope="prototype" class="com.neuedu.Bean.Page">

<constructor-arg value="123" type="int"></constructor-arg>

<constructor-arg value="456" type="String"></constructor-arg>

</bean>

  

Scope屬性:ide

Prototype:每次從容器中調用Bean時,都返回一個新的實例,即每次調用getBean()時,至關於執行new XxxBean()的操做測試

Request:每次Http請求都會建立一個新的Bean, 僅適用於WebApplication環境

Session:每次建立一個session,建立對象,同一個Http Session共享一個Bean,不一樣的HttpSession使用不一樣的Bean。僅適用於WebApplication環境

Singleton:Spring容器中僅存在一個Bean實例,Bean以單例的方式存在

 

實驗22:建立帶有生命週期方法的bean

<bean id="page" scope="singleton" class="com.neuedu.Bean.Page" init-method="int" destroy-method="destroy">

<constructor-arg value="123" type="int"></constructor-arg>

<constructor-arg value="456" type="String"></constructor-arg>

</bean>

  

 

實驗20bean之間的依賴 depends-on="order"被依賴的對象會先建立

<bean id="page" scope="singleton" class="com.neuedu.Bean.Page" depends-on="font">

<constructor-arg value="123" type="int"></constructor-arg>

<constructor-arg value="456" type="String"></constructor-arg>

</bean>

<bean id="font" class="com.neuedu.Bean.Font"></bean>

  

 

實驗18:經過繼承實現bean配置信息的重用

<bean id="Book"  class="com.neuedu.Bean.Book" 

p:name="四大名著"

p:num="258"

 />

 

 <bean id="Book2"  parent="Book"

p:num="254"

 />

  

 

實驗19:經過abstract屬性建立一個模板bean

<bean id="Book"  abstract="true" class="com.neuedu.Bean.Book" 

p:name="四大名著"

p:num="258"

 />

 

 <bean id="Book2"  parent="Book"

p:num="254"

 />

  

 

實驗7:測試使用null

<bean id="page" scope="singleton" class="com.neuedu.Bean.Page" >

<property name="fontSize">

<null/>

</property>

</bean>

  

null只有包裝類和引用類型能夠用

 

實驗8:引用其餘bean

<bean id="Book" class="com.neuedu.Bean.Book">

<property name="page" ref="page"></property>

</bean>

  

 

實驗9:引用內部bean

<bean id="Book" class="com.neuedu.Bean.Book">

<property name="page" >

<bean id="page" scope="singleton" class="com.neuedu.Bean.Page" >

<property name="fontSize" value="123"></property>

</bean>

</property>

</bean>

  

 

實驗10:使用List類型的集合屬性

<bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petList" ref="petList" />

</bean>

 

<util:list id="petList" list-class="java.util.ArrayList" value-type="java.lang.String">

<value>DOG</value>

<value>CAT</value>

<value>BIRD</value>

</util:list>

  

 

實驗11:使用Map類型的集合屬性

<!-- 第一種寫法 ,經過ref引用,此時須要在 uitl-map中聲明id 推薦這種寫法

<bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petMap" ref="petMap" />

</bean>

<util:map id="petMap" map-class="java.util.HashMap">

<entry key="101" value="dog" />

<entry key="103" value="wolf" />

<entry key="105" value="bird" />

</util:map> --> 

 

<!-- 第二種寫法,嵌入內部 -->

<bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petMap">

<util:map map-class="java.util.HashMap">

<!-- 能夠經過map-class顯示指定Map的實現類 -->

<entry key="101" value="dog" />

<entry key="103" value="wolf" />

<entry key="105" value="bird" />

</util:map>

</property>

</bean>

  

 

實驗12:使用prop子元素爲Properties類型的屬性賦值

<bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petProperties" ref="petProperties" />

</bean>

 

<util:properties id="petProperties">

<prop key="151">PIG</prop>

<prop key="153">PINGUIN</prop>

</util:properties>

  

 

 

實驗15:配置經過靜態工廠方法建立的bean[經過靜態方法提供實例對象,工廠類自己不須要實例化!]

<bean id="staticFactory" class="com.neuedu.spring.bean.StaticFactory" factory-method="getBook">

<constructor-arg value="book01"></constructor-arg>

</bean>

  

 

實驗16:配置經過實例工廠方法建立的bean[經過實例方法提供實例對象,工廠類自己須要先建立對象!]

<bean id="instanceFactory" class="com.neuedu.spring.bean.InstanceFactory"></bean>

<bean id="bookFromInstanceFactory" factory-bean="instanceFactory" factory-method="getBook">

<constructor-arg value="book02"></constructor-arg>

</bean>

  

 

實驗17:配置FactoryBean

public class MyFactoryBean implements FactoryBean<Book> {

 

@Override

public Book getObject() throws Exception {

return new Book(22, "無字天書", "好啊", 22.5);

}

 

@Override

public Class<?> getObjectType() {

return Book.class;

}

 

@Override

public boolean isSingleton() {

return false;

}

}

  

 

實驗22[補充]:測試bean的後置處理器

 

①在bean的初始化方法調用先後執行操做的專門的對象

②自定義後置處理器實現該接口:org.springframework.beans.factory.config.BeanPostProcessor

 

③在springmvc中配置一下該bean對象.

<bean class="com.neuedu.spring.bean.Book" init-method="init"></bean>

<bean id="myBeanPostProcessor" class="com.neuedu.spring.bean.MyBeanPostProcessor"></bean>

  

 

數據庫鏈接池:

6) 數據庫鏈接池

> 數據庫鏈接池就是存放數據庫鏈接(Connection)的集合

> 咱們獲取一個數據庫鏈接是一個相對很麻煩的過程,

若是咱們獲取一個數據庫鏈接,使用一次之後就給它關閉了

下一次再去使用的時候就要從新建立一個新的數據庫鏈接。

> 因此咱們提出了一個數據庫鏈接池的概念,數據庫鏈接池放的都是數據庫鏈接(Connection

咱們在去使用數據庫鏈接時候,不用再去從新建立數據庫鏈接,而是直接從池中獲取,

使用完的數據庫鏈接,也不是直接銷燬,而是要放回到鏈接池。

>

數據庫鏈接池的常見的屬性:

 

初始鏈接數量:數據鏈接池建立之後,保存數據庫鏈接的數量[50]

最小空閒鏈接數:數據庫鏈接池最少得未使用的數據庫鏈接的數量[10]

最大空閒鏈接數:數據庫鏈接池最大閒置鏈接數,當閒置鏈接數滿了之後,將不會有其餘鏈接進入池

每次增長鏈接數:當數據庫鏈接都被佔用之後,一次性增長的數據庫鏈接的個數[20]

最大鏈接數:數據庫鏈接池的最大容量,當最大鏈接數飽和了,則再也不建立新的數據庫鏈接[100]

最大等待時間:當數據庫鏈接池飽和之後,等待獲取數據庫鏈接的時間

 

> 常見的數據庫鏈接池

- 全部的數據庫鏈接池都須要實現DataSource,當使用數據庫鏈接池是,咱們便再也不須要使用DriverManger獲取數據庫鏈接

而是使用DataSource

 - Connection getConnection()

- 從數據庫鏈接池中獲取數據庫鏈接對象

 

1.DBCP

- DBCPApache出品的一款數據庫鏈接

- DBCP依賴於commons-pool

- 使用DBCP須要導入兩個jar包:

commons-dbcp-1.4.jar

commons-pool-1.5.5.jar

- 當咱們經過數據庫鏈接池獲取數據庫鏈接之後,咱們所獲取到數據庫鏈接已經不是咱們熟悉的那個Connection

數據庫鏈接池對Connection對象進行了包裝,它修改Connectionclose()方法,

再去調用close()數據庫鏈接將不會真的關閉,而是要放回到數據庫鏈接池中,供其餘線程使用。

- 核心類:

BasicDataSourceFactory

 

2.C3P0(重點)

- C3P0使用的是XML做爲配置文件

- 使用c3p0須要導入一個jar包:

c3p0-0.9.1.2.jar

- 導入c3p0的配置文件:

1.配置文件的名字:c3p0-cofig.xml

2.配置文件要求放到類路徑下(src

- 核心類:

ComboPooledDataSource

- 注意:

DataSource就至關於池子,咱們的數據庫鏈接都是從DataSource中獲取的,

若是程序中有多個DataSource的實例,那麼咱們說你還不如不用數據庫鏈接池。

因此咱們的DataSource在項目中應該只有一個實例。

 

 

實驗23:引用外部屬性文件★

jdbc.properties文件:

jdbc.user=root

jdbc.passowrd=123456

jdbc.url=jdbc:mysql://localhost:3306/test

jdbc.driver=com.mysql.jdbc.Driver

 

<context:property-placeholder location="classpath:jdbc.properties"/>

 

1.在目標屬性上加@Value註解

@Value("${jdbc.user}")

private String username;

2.

<!-- 根據外部屬性文件中的信息配置數據源 -->

<bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

<property name="user" value="${jdbc.user}"></property>

<property name="password" value="${jdbc.passowrd}"></property>

<property name="jdbcUrl" value="${jdbc.url}"></property>

<property name="driverClass" value="${jdbc.driver}"></property>

</bean>

 

 

ComboPooledDataSource bean = ioc.getBean(ComboPooledDataSource.class);

Connection connection = bean.getConnection();

System.out.println(connection);

Statement st = connection.createStatement();

ResultSet rs = st.executeQuery("select * from stu");

while(rs.next()){

String string = rs.getString("name");

String string2 = rs.getString("school");

System.out.println(string+"==="+string2);

}

  

 

 

實驗24:基於XML的屬性裝配

①手動裝配

<!-- 屬性的裝配:手動裝配 -->

<bean id="userService" class="com.neuedu.spring.bean.UserService"></bean>

<bean  id="userAction" class="com.neuedu.spring.bean.UserAction">

<property name="userService" ref="userService"></property>

</bean>

  

 

②自動裝配

<!-- 1.按類型裝配:byType -->

<!-- 首先檢測當前bean中須要裝配的屬性的類型 -->

<!-- 而後在IOC容器中查找匹配這個類型的bean -->

<!-- 若是類型匹配的bean是惟一的,那麼就將這個匹配的bean注入到userAction中 -->

 

<bean id="userService" class="com.neuedu.spring.bean.UserService"></bean>

<bean  id="userAction" autowire="byType" class="com.neuedu.spring.bean.UserAction"></bean>

 

<!-- 2.按bean的id值裝配:byName -->

<!-- 首先檢測當前bean中須要裝配的屬性的屬性名,屬性名是將setXxx()方法去掉set,首字母小寫獲得的 -->

<!-- 而後根據屬性名做爲id的值,在IOC容器中查找對應的bean -->

<!-- 若是可以找到,則將找到bean注入進去 -->

  

 

 

 

6SpEL簡介【見WORLD文檔---瞭解】

Spring Expression LanguageSpring表達式語言,簡稱SpEL。支持運行時查詢並能夠操做對象圖。

JSP頁面上的EL表達式、Struts2中用到的OGNL表達式同樣,SpEL根據JavaBean風格的getXxx()setXxx()方法定義的屬性訪問對象圖,徹底符合咱們熟悉的操做習慣。

 

6.1 基本語法

SpEL使用#{}做爲定界符,全部在大框號中的字符都將被認爲是SpEL表達式。

 

6.2 使用字面量

●整數:<property name="count" value="#{5}"/>

●小數:<property name="frequency" value="#{89.7}"/>

●科學計數法:<property name="capacity" value="#{1e4}"/>

String類型的字面量可使用單引號或者雙引號做爲字符串的定界符號

<property name=namevalue="#{'Chuck'}"/>

<property name='name' value='#{"Chuck"}'/>

Boolean<property name="enabled" value="#{false}"/>

 

 

實驗25[SpEL測試I]SpEL中使用字面量

實驗26[SpEL測試II]SpEL中引用其餘bean

實驗27[SpEL測試III]SpEL中引用其餘bean的某個屬性值

實驗28[SpEL測試IV]SpEL中調用非靜態方法

實驗29[SpEL測試V]SpEL中調用靜態方法

實驗30[SpEL測試VI]SpEL中使用運算符

 

 

8.使用註解配置bean

①聲明bean的註解

@Component 將當前類聲明爲IOC容器中的一個普通的組件

@Controller 將當前類聲明爲IOC容器中的一個控制器組件

@Service 將當前類聲明爲IOC容器中的業務邏輯層組件

@Repository 將當前類聲明爲IOC容器中的一個持久化層組件

@ControllerAdvice

 

Spring根據上述註解其實並不能分辨當前類是否真的是一個控制器或Dao,即便標記的類和註解不對應也沒有語法錯誤。

但在實際工做中,確定要將專門的註解標記在對應的類上面。

 

②使用基於註解的bean的配置,須要額外導入一個jar包:spring-aop-4.0.0.RELEASE.jar

 

③須要設置自動掃描的包

< context:component-scan base-package ="com.neuedu.ioc.bean"/>

 

 

④使用註解後,默認按照類名首字母小寫做爲id的值,也可使用value屬性指定idvalue屬性名也能夠省略註解

註解 id值

@Component                    

public class CommonComponent {

}

  commonComponent

@Controller(value="neueduBookAction" )         

public class BookAction {

 

}

neueduBookAction

@Service("happyService" )                    

public class BookService {

 

}

 happyService

 

 

實驗31:經過註解分別建立DaoServiceController

實驗32:使用context:include-filter指定掃描包時要包含的類

實驗33:使用context:exclude-filter指定掃描包時不包含的類

 

< context:component-scan base-package ="com.neuedu.ioc.bean"/>

[1]base-package屬性指定一個須要掃描的基類包,Spring容器將會掃描這個基類包及其子包中的全部類。

[2]當須要掃描多個包時可使用逗號分隔,

[3]若是僅但願掃描特定的類而非基包下的全部類,可以使用resource-pattern屬性過濾特定的類,示例:

<context:component-scan base-package="com.neuedu.component" resource-pattern="autowire/*.class"/>

[4]包含與排除

<context:include-filter>子節點表示要包含的目標類

注意:一般須要與use-default-filters屬性配合使用纔可以達到「僅包含某些組件」這樣的效果。

即:經過將use-default-filters屬性設置爲false,禁用默認過濾器,而後掃描的就只是include-filter中的規則

指定的組件了。

<context:exclude-filter>子節點表示要排除在外的目標類

component-scan下能夠擁有若干個include-filtejrexclude-filter子節

 

⑤使用註解進行自動裝配:@Autowired註解[好處就是:連getset方法都不用寫!]

[1]首先檢測標記了@Autowired註解的屬性的類型

[2]根據類型進行裝配

[3]若是指定類型的bean不止一個,那麼根據須要被裝配的屬性的屬性名作id的值,查找bean

[4]若是根據id值仍是沒有找到bean,可使用@Qualifier註解手動指定要裝配的beanid.

 

實驗34:使用@Autowired註解實現根據類型實現自動裝配★

實驗34[補充1]:若是資源類型的bean不止一個,默認根據@Autowired註解標記的成員變量名做爲id查找bean,進行裝配★

實驗34[補充2]:若是根據成員變量名做爲id仍是找不到bean,可使用@Qualifier註解明確指定目標beanid

實驗36Autowired註解的required屬性指定某個屬性容許不被設置.

實驗37:在類上使用註解@Scope能夠指定對象是單實例仍是多實例的!

相關文章
相關標籤/搜索