1.實例化spring容器 和 從容器獲取Bean對象
實例化Spring容器常用的兩種方式:
方法一:
在類路徑下尋找配置文件來實例化容器 [推薦使用]
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
方法二:
在文件系統路徑下尋找配置文件來實例化容器 [這種方式可以在開發階段使用]
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多個,可以通過String數組傳入。
當spring容器啟動后,因為spring容器可以管理bean對象的創建,銷毀等生命周期,
所以我們只需從容器直接獲取Bean對象就行,而不用編寫一句代碼來創建bean對象。
從容器獲取bean對象的代碼如下:
ApplicationContext ctx = new ClassPathXmlApplicationContext(“beans.xml”);
OrderService service = (OrderService)ctx.getBean("personService");
2.Spring實例化Bean的三種方式
以下是三種方式的例子:
1.使用類構造器實例化 [默認的類構造器] <bean id=“orderService" class="cn.itcast.OrderServiceBean"/> 2.使用靜態工廠方法實例化 <bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/> public class OrderFactory { public static OrderServiceBean createOrder(){ // 注意這里的這個方法是 static 的! return new OrderServiceBean(); } } 3.使用實例工廠方法實例化: <bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/> <bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/> public class OrderFactory { public OrderServiceBean createOrder(){ return new OrderServiceBean(); } }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
3.Bean的生命周期 (Bean的作用域)
bean的scope 屬性
The scope of this bean: typically "singleton" (one shared instance, which will be returned by all calls
to getBean with the given id), or "prototype" (independent instance resulting from each call to
getBean). Default is "singleton". Singletons are most commonly used, and are ideal for multi-
threaded service objects. Further scopes, such as "request" or "session", might be supported by
extended bean factories (e.g. in a web environment). Note: This attribute will not be inherited by
child bean definitions. Hence, it needs to be specified per concrete bean definition. Inner bean
definitions inherit the singleton status of their containing bean definition, unless explicitly specified:
The inner bean will be a singleton if the containing bean is a singleton, and a prototype if the
containing bean has any other scope.
.singleton [單例]
eg:<bean id="personService" class="com.yinger.service.impl.PersonServiceBean" scope="singleton"></bean>
在每個Spring IoC容器中一個bean定義只有一個對象實例。
請注意Spring的singleton bean概念與“四人幫”(GoF)模式一書中定義的Singleton模式是完全不同的。
經典的GoF Singleton模式中所謂的對象范圍是指在每一個ClassLoader
中指定class創建的實例有且僅有一個。
把Spring的singleton作用域描述成一個container
對應一個bean實例最為貼切。亦即,假如在單個Spring容器內定義了某個指定class的bean,
那么Spring容器將會創建一個且僅有一個由該bean定義指定的類實例。
默認情況下會在容器啟動時初始化bean,但我們可以指定Bean節點的lazy-init=“true”來延遲初始化bean,這時候,只有第一次獲取bean會才初始化bean。
如:<bean id="xxx" class="cn.itcast.OrderServiceBean" lazy-init="true"/>
如果想對所有bean都應用延遲初始化,可以在根節點beans設置default-lazy-init=“true“,如下:
<beans default-lazy-init="true“ ...>
.prototype [原型]
每次從容器獲取bean都是新的對象。
對于prototype作用域的bean,有一點非常重要,那就是Spring不能對一個prototype bean的整個生命周期負責:容器在初始化、配置、裝飾或者是
裝配完一個prototype實例后,將它交給客戶端,隨后就對該prototype實例不聞不問了。不管何種作用域,容器都會調用所有對象的初始化生命周期回調方法。
但對prototype而言,任何配置好的析構生命周期回調方法都將不會被調用。清除prototype作用域的對象并釋放任何prototype bean所持有的昂貴資源,
都是客戶端代碼的職責。(讓Spring容器釋放被prototype作用域bean占用資源的一種可行方式是,通過使用bean的后置處理器,該處理器持有要被清除的bean的引用。)
以下的三種scope只是在web應用中才可以使用
.request
.session
.global session
使用這三種配置之前要先初始化Web配置
RequestContextListener
和RequestContextFilter
兩個類做的都是同樣的工作: 將HTTP request對象綁定到為該請求提供服務的Thread
。
這使得具有request和session作用域的bean能夠在后面的調用鏈中被訪問到。
指定Bean的初始化方法和銷毀方法
<bean id="xxx" class="cn.itcast.OrderServiceBean" init-method="init" destroy-method="close"/>
Spring提供了幾個標志接口(marker interface),這些接口用來改變容器中bean的行為;它們包括InitializingBean
和DisposableBean
。
現這兩個接口的bean在初始化和析構時容器會調用前者的afterPropertiesSet()
方法,以及后者的destroy()
方法。
Spring在內部使用BeanPostProcessor
實現來處理它能找到的任何標志接口并調用相應的方法。
如果你需要自定義特性或者生命周期行為,你可以實現自己的 BeanPostProcessor
。
初始化回調和析構回調:
測試:
bean對象:
package com.yinger.service.impl; public class PersonServiceBean implements com.yinger.service.PersonService{ //構造器 public PersonServiceBean(){ System.out.println("instance me"); } //save方法 public void save() { System.out.println("save"); } //初始化方法,這個方法是類被實例化了之后就會執行的! public void init(){ System.out.println("init"); } //銷毀方法 public void destroy(){ System.out.println("destroy"); } }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
JUnit Test:
package com.yinger.test; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.yinger.service.PersonService; public class SpringTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test //創建的單元測試 public void testSave() { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); System.out.println("--------"); PersonService ps = (PersonService)ctx.getBean("personService"); ps.save(); ctx.close(); //有了這一句才會有destroy方法的調用 } }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
beans.xml 設置:
如果lazy-init(默認是default,也就是false)沒有設置,或者設置為default或者false
<bean id="personService" class="com.yinger.service.impl.PersonServiceBean" scope="singleton" init-method="init" destroy-method="destroy" lazy-init="false"></bean>.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
那么結果是:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
instance me
init
--------
save
destroy
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
反之,如果設置為true,結果是:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
--------
instance me
init
save
destroy
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
修改測試代碼:
@Test public void testSave() { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); // System.out.println("--------"); PersonService ps = (PersonService)ctx.getBean("personService"); PersonService ps1 = (PersonService)ctx.getBean("personService"); System.out.println(ps==ps1); // ps.save(); ctx.close(); }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
重新測試:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext). log4j:WARN Please initialize the log4j system properly. instance me init true destroy.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
[在scope為singleton時,每次使用getBean得到的都是同一個bean,同一個對象]
修改bean中的scope屬性:scope="prototype"
測試結果:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext). log4j:WARN Please initialize the log4j system properly. instance me init instance me init false.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
[在scope為prototype時,每次得到的bean對象都是不同的,從上面可以看出實例化了兩個對象,最終的比較是false]
4.依賴注入
來自Spring參考文檔:依賴注入(DI)背后的基本原理是對象之間的依賴關系(即一起工作的其它對象)只會通過以下幾種方式來實現:構造器的參數、工廠方法的參數,
或給由構造函數或者工廠方法創建的對象設置屬性。因此,容器的工作就是創建bean時注入那些依賴關系。
相對于由bean自己來控制其實例化、直接在構造器中指定依賴關系或者類似服務定位器(Service Locator)模式這3種自主控制依賴關系注入的方法來說,
控制從根本上發生了倒轉,這也正是控制反轉(Inversion of Control, IoC) 名字的由來。
(1)基本類型的注入:
基本類型對象注入: <bean id="orderService" class="cn.itcast.service.OrderServiceBean"> <constructor-arg index=“0” type=“java.lang.String” value=“xxx”/>//構造器注入 <property name=“name” value=“zhao/>//屬性setter方法注入 </bean> 注入其他bean:
方式一 <bean id="orderDao" class="cn.itcast.service.OrderDaoBean"/> <bean id="orderService" class="cn.itcast.service.OrderServiceBean"> <property name="orderDao" ref="orderDao"/> </bean> 方式二(使用內部bean,但該bean不能被其他bean使用) <bean id="orderService" class="cn.itcast.service.OrderServiceBean"> <property name="orderDao"> <bean class="cn.itcast.service.OrderDaoBean"/> </property> </bean>.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
測試 構造器和setter 方式注入:
新建一個DAO的接口:
package com.yinger.dao; public interface PersonDao { public void save(); }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
新建一個接口的實現類:
package com.yinger.dao.impl; import com.yinger.dao.PersonDao; public class PersonDaoBean implements PersonDao{ public void save() { System.out.println("PersonDaoBean.save()"); } }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
修改原有的PersonServiceBean,添加兩個字段:
package com.yinger.service.impl; import com.yinger.dao.PersonDao; import com.yinger.service.PersonService; public class PersonServiceBean implements PersonService{ private PersonDao pDao;//這樣設計就實現了業務層和數據層的徹底解耦 private String name; //默認的構造器 public PersonServiceBean(){ System.out.println("instance me"); } //帶參數的構造器 public PersonServiceBean(PersonDao pDao){ this.pDao=pDao; } //帶參數的構造器 public PersonServiceBean(PersonDao pDao,String name){ this.pDao=pDao; this.name=name; } //save方法 public void save() { // System.out.println("save"); pDao.save(); System.out.println(this.getName()); } //初始化方法,這個方法是類被實例化了之后就會執行的! public void init(){ System.out.println("init"); } //銷毀方法 public void destroy(){ System.out.println("destroy"); } public String getName() { return name; } public void setName(String name) { this.name = name; } }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
修改beans.xml:
<bean id="personService" class="com.yinger.service.impl.PersonServiceBean"> <constructor-arg index="0"> <bean id="pDao" class="com.yinger.dao.impl.PersonDaoBean"></bean> </constructor-arg> <constructor-arg index="1" type="java.lang.String" value="name" /> </bean>.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
新增一個測試方法:
@Test public void testInjection() { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); System.out.println("--------"); PersonService ps = (PersonService)ctx.getBean("personService"); ps.save(); ctx.close(); }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
測試結果:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
--------
PersonDaoBean.save()
name
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
如果在beans.xml中再添加一句:
<property name="name" value="name2"></property>
重新測試,結果是:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
--------
PersonDaoBean.save()
name2
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
(2)集合類型的注入:
集合類型的裝配:
public class OrderServiceBean { private Set<String> sets = new HashSet<String>(); private List<String> lists = new ArrayList<String>(); private Properties properties = new Properties(); private Map<String, String> maps = new HashMap<String, String>(); ....//這里省略屬性的getter和setter方法 }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
XML配置:
<bean id="order" class="cn.itcast.service.OrderServiceBean"> <property name="lists"> <list> <value>lihuoming</value> </list> </property> <property name="sets"> <set> <value>set</value> </set> </property> <property name="maps"> <map> <entry key="lihuoming" value="28"/> </map> </property> <property name="properties"> <props> <prop key="12">sss</prop> </props> </property> </bean>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
補充:Spring對泛型的支持
(3)三種依賴注入的方式 和 兩種裝配方式:
①使用構造器注入
②使用屬性setter方法注入:
通過調用無參構造器或無參static
工廠方法實例化bean之后,調用該bean的setter方法,即可實現基于setter的DI。
Spring開發團隊提倡使用setter注入。而且setter DI在以后的某個時候還可將實例重新配置(或重新注入)
③使用Field注入(用于注解方式)
處理bean依賴關系通常按以下步驟進行:
-
根據定義bean的配置(文件)創建并初始化
BeanFactory
實例(大部份的Spring用戶使用支持XML格式配置文件的BeanFactory
或ApplicationContext
實現)。 -
每個bean的依賴將以屬性、構造器參數、或靜態工廠方法參數的形式出現。當這些bean被實際創建時,這些依賴也將會提供給該bean。
-
每個屬性或構造器參數既可以是一個實際的值,也可以是對該容器中另一個bean的引用。
-
每個指定的屬性或構造器參數值必須能夠被轉換成特定的格式或構造參數所需的類型。默認情況下,Spring會以String類型提供值轉換成各種內置類型,
比如int
、long
、String
、boolean
等。
在<constructor-arg/>
或<property/>
元素內部還可以使用ref
元素。該元素用來將bean中指定屬性的值設置為對容器中的另外一個bean的引用。
注意:內部bean中的scope
標記及id
或name
屬性將被忽略。內部bean總是匿名的且它們總是prototype模式的。同時將內部bean注入到包含該內部bean之外的bean是不可能的。
注入依賴對象可以采用手工裝配或自動裝配,在實際應用中建議使用手工裝配,因為自動裝配會產生未知情況,開發人員無法預見最終的裝配結果。
1.手工裝配依賴對象
2.自動裝配依賴對象
<1>手工裝配
手工裝配依賴對象,在這種方式中又有兩種編程方式
1. 在xml配置文件中,通過在bean節點下配置,如
<bean id="orderService" class="cn.itcast.service.OrderServiceBean"> <constructor-arg index=“0” type=“java.lang.String” value=“xxx”/>//構造器注入 <property name=“name” value=“zhao”/>//屬性setter方法注入 </bean>.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
2. 在java代碼中使用@Autowired或@Resource注解方式進行裝配。但我們需要在xml配置文件中配置以下信息:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"//注意這里,要添加的,還有下面的兩個紅色部分 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config/> </beans>.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
這個配置隱式注冊了多個對注釋進行解析處理的處理器:AutowiredAnnotationBeanPostProcessor,
CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
注: @Resource注解在spring安裝目錄的lib\j2ee\common-annotations.jar
* 注解方式的講解
在java代碼中使用@Autowired或@Resource注解方式進行裝配,這兩個注解的區別是:
@Autowired 默認按類型裝配,@Resource默認按名稱裝配,當找不到與名稱匹配的bean才會按類型裝配。 @Autowired private PersonDao personDao;//用于字段上 @Autowired public void setOrderDao(OrderDao orderDao) {//用于屬性的setter方法上 this.orderDao = orderDao; } @Autowired注解是按類型裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它required屬性為false。
如果我們想使用按名稱裝配,可以結合@Qualifier注解一起使用。如下: @Autowired @Qualifier("personDaoBean") private PersonDao personDao;
注:@Autowired 注解可以使用在很多地方,包括了 集合類型,Map,來自ApplicationContext的特殊類型的所有 beans等等
特殊的情況:多個構造器
雖然當 一個類只有一個連接構造器時它將被標記為 required, 但是還是可以標記多個構造器的。在這種情況下,每一個構造器都有可能被認為是連接構造器,
Spring 將會把依賴關系能夠滿足的構造器認為是greediest 的構造器
測試:@Autowired注解 [如果兩個構造器都使用了該注解會報錯!所以,在多個構造器的情況下,要多多考慮]
新建一個PersonServiceBean2類:其中有三處使用了 @Autowired注解 ,只要其中一個位置包含了注解就行[測試時]
package com.yinger.service.impl; import org.springframework.beans.factory.annotation.Autowired; import com.yinger.dao.PersonDao; import com.yinger.service.PersonService; public class PersonServiceBean2 implements PersonService{ //Autowired默認是按照類型來裝配,這里是放在字段上 @Autowired private PersonDao pDao;//這樣設計就實現了業務層和數據層的徹底解耦 //默認的構造器 public PersonServiceBean2(){ System.out.println("instance me"); } //帶參數的構造器 @Autowired //放在構造方法上 public PersonServiceBean2(PersonDao pDao){ this.pDao=pDao; } //save方法 public void save() { pDao.save(); } //初始化方法,這個方法是類被實例化了之后就會執行的! public void init(){ System.out.println("init"); } //銷毀方法 public void destroy(){ System.out.println("destroy"); } public PersonDao getpDao() { return pDao; } @Autowired //放在屬性的setter上 public void setpDao(PersonDao pDao) { this.pDao = pDao; } }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
beans.xml:
<context:annotation-config/> <bean id="personService2" class="com.yinger.service.impl.PersonServiceBean2"></bean> <bean id="personDao" class="com.yinger.dao.impl.PersonDaoBean"></bean>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
測試方法:
@Test //用于測試依賴注入的方法 public void testInjection() { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); System.out.println("--------"); PersonService ps = (PersonService)ctx.getBean("personService2"); ps.save(); ctx.close(); }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
測試結果:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
--------
PersonDaoBean.save()
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
從結果中可以看出,PersonDao是注入進去了!
[還有一個要注意,按照類型查找,并不是類型一定要完全吻合,可以是屬性(字段,方法參數)的實現類(如果以上的是接口),上面的實例就是一個例子]
@Resource注解和@Autowired一樣,也可以標注在字段或屬性的setter方法上,但它默認按名稱裝配。
名稱可以通過@Resource的name屬性指定,如果沒有指定name屬性,當注解標注在字段上,
即默認取字段的名稱作為bean名稱尋找依賴對象,當注解標注在屬性的setter方法上,即默認取屬性名作為bean名稱尋找依賴對象。 [推薦使用的方式] @Resource(name=“personDaoBean”) private PersonDao personDao;//用于字段上 注意:如果沒有指定name屬性,并且按照默認的名稱仍然找不到依賴對象時, @Resource注解會回退到按類型裝配。
但一旦指定了name屬性,就只能按名稱裝配了。.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
測試: 測試時使用下面的一個注解就可以了
新建類PersonServiceBean3:
package com.yinger.service.impl; import javax.annotation.Resource; import com.yinger.dao.PersonDao; import com.yinger.service.PersonService; public class PersonServiceBean3 implements PersonService{ //Resource默認是按照名稱來裝配,這里是放在字段上 @Resource private PersonDao pDao;//這樣設計就實現了業務層和數據層的徹底解耦 //默認的構造器 public PersonServiceBean3(){ System.out.println("instance me"); } //帶參數的構造器 public PersonServiceBean3(PersonDao pDao){ this.pDao=pDao; } //save方法 public void save() { pDao.save(); } //初始化方法,這個方法是類被實例化了之后就會執行的! public void init(){ System.out.println("init"); } //銷毀方法 public void destroy(){ System.out.println("destroy"); } public PersonDao getpDao() { return pDao; } @Resource //放在屬性的setter上 public void setpDao(PersonDao pDao) { this.pDao = pDao; } }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
beans.xml中的配置:
<context:annotation-config/> <bean id="personService3" class="com.yinger.service.impl.PersonServiceBean3"></bean> <bean id="pDao" class="com.yinger.dao.impl.PersonDaoBean"></bean>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
測試結果:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
instance me
--------
PersonDaoBean.save()
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
注:beans.xml中第二個bean的id也可以是其他的名稱,例如personDao,同樣是上面的結果,因為
如果沒有指定name屬性,并且按照默認的名稱仍然找不到依賴對象時, @Resource注解會回退到按類型裝配。
<2>自動裝配:
對于自動裝配,大家了解一下就可以了,實在不推薦大家使用。例子:
<bean id="..." class="..." autowire="byType"/>
autowire屬性取值如下:
byType:按類型裝配,可以根據屬性的類型,在容器中尋找跟該類型匹配的bean。如果發現多個,那么將會拋出異常。如果沒有找到,即屬性值為null。
byName:按名稱裝配,可以根據屬性的名稱,在容器中尋找跟該屬性名相同的bean,如果沒有找到,即屬性值為null。
constructor與byType的方式類似,不同之處在于它應用于構造器參數。如果在容器中沒有找到與構造器參數類型一致的bean,那么將會拋出異常。
autodetect:通過bean類的自省機制(introspection)來決定是使用constructor還是byType方式進行自動裝配。如果發現默認的構造器,那么將使用byType方式。
你也可以針對單個bean設置其是否為被自動裝配對象。當采用XML格式配置bean時,<bean/>
元素的 autowire-candidate
屬性可被設為false
,這樣容器在查找自動裝配對象時將不考慮該bean。
5. 通過在classpath自動掃描方式把組件納入spring容器中管理
前面的例子我們都是使用XML的bean定義來配置組件。在一個稍大的項目中,通常會有上百個組件,如果這些這組件采用xml的bean定義來配置,
顯然會增加配置文件的體積,查找及維護起來也不太方便。spring2.5為我們引入了組件自動掃描機制,他可以在類路徑底下尋找標注了@Component、
@Service、@Controller、@Repository注解的類,并把這些類納入進spring容器中管理。
它的作用和在xml文件中使用bean節點配置組件是一樣的。要使用自動掃描機制,我們需要打開以下配置信息:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="cn.itcast"/> </beans>.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
其中base-package為需要掃描的包(含子包)。
@Service用于標注業務層組件、 @Controller用于標注控制層組件(如struts中的action)、@Repository用于標注數據訪問組件,即DAO組件。而@Component泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注。
測試:
在上面的例子中,添加如下內容:
@Service("personService3") public class PersonServiceBean3 implements PersonService{
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
@Repository public class PersonDaoBean implements PersonDao{
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
同時,在beans.xml中添加:
<context:component-scan base-package="com.yinger.dao.impl"></context:component-scan> <context:component-scan base-package="com.yinger.service.impl"></context:component-scan>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
測試方法不變,結果還是一樣:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
instance me
--------
PersonDaoBean.save()
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
6. 編碼剖析Spring管理Bean 和 依賴注入
略過……