## 4.9 基于注解的容器配置
配置Spring時,注解要比XML更好嗎? 基于注解配置的介紹就提出了這樣的問題,這種方法要比XML‘更好’嗎?簡短的回答就是具體問題具體分析。完整的答案就是每種方法都有它的利與弊,通常是讓開發 人員來決定使用哪種策略更適合使用。由于定義它們的方式,注解在它們的聲明中提供了大量的上下文,使得配置更加簡短和簡潔。然而,XML更擅長裝配組件,而不需要觸碰它們源代碼或重新編譯。一些開發人員更喜歡裝配源碼而其他人認為被注解的類不再 是POJO了,此外,配置變得分散并且難以控制。
無論怎么去線則,Spring都可以容納兩種方式,甚至是它們的混合體。最值得指出 的是通過JavaConfig(4.12節)選擇,Spring允許以非侵入式的方式來使用注解,而不需 要觸碰目標組件的源代碼和工具,所有的配置方式都是[SpringSource Tool Suite](http://www.springsource.com/products/sts)所支持的。
作為 XML 配置的另外一種選擇,依靠字節碼元數據的基于注解的配置來裝配組件代替 了尖括號式的聲明。作為使用 XML 來表述 bean 裝配的替換,開發人員可以將配置信息移入 到組件類本身中,在相關的類,方法或字段聲明上使用注解。正如在 4.8.1.2 節,“示例: RequiredAnnotationBeanPostProcessor”所提到的,使用 BeanPostProcessor 來連接注解是擴展 Spring IoC 容器的一種常用方式。比如,Spring 2.0 引入的使用@Required(4.9.1 節)注解來強制所需屬性的可能性。在 Spring 2.5 中,可以使用相同的處理方法來驅 動 Spring 的依賴注入。從本質上來說,@Autowired 注解提供了在 4.4.5 節,“自動裝配協 作者”中描述的相同能力,但卻有更細粒度的控制和更廣泛的適用性。Spring 2.5 也添加了 對 JSR-250 注解的支持,比如@Resource,@PostConstruct 和@PreDestroy。Spring 3.0 添加了對 JSR-330(對 Java 的依賴注入)注解的支持,包含在 javax.inject 包下,比如@Inject,@Qualifier,@Named 和@Provider,當 JSR330 的 jar 包在類路徑下時就可以使用。使 用這些注解也需要在 Spring 容器中注冊特定的 BeanPostProcessor。
> 
> 注意
> 注解注入會在 XML 注入之前執行,因此通過兩種方式,那么后面的配置會覆蓋前面裝 配的屬性。
一如往常,你可以注冊它們作為獨立的 bean,但是它們也可以通過包含下面的基于 XML的 Spring 配置代碼片段被隱式地注冊(注意要包含 context 命名空間):
```
<?xml version="1.0" encoding="UTF-8"?>
<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/bean[s http://www.springframework.org/schema/beans/spring -beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
</beans>
```
( 隱 式 注 冊 的 后 處 理 器 包 含 AutowiredAnnotationBeanPostProcessor , CommonAnnotationBeanPostProcessor , PersistenceAnnotationBeanPostProcessor , 以 及 上 述 的 RequiredAnnotationBeanPostProcessor)
> 
> 注意
> `<context:annotation-config/>`僅僅查找定義在同一上下文中的 bean 的注解。 這就意味著,如果你為 DispatcherServlet 將`<context:annotation-config/>`放 置在 WebApplicationContext 中,那么它僅僅檢查控制器中的@Autowired bean,而 不是你的服務層 bean,可以參看 16.2 節,“DispatcherServlet”來查看更多信息。
### 4.9.1 @Required
@Required 注解應用于 bean 屬性的 setter 方法,就向下面這個示例:
```
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Required
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
```
這個注解只是表明受影響的 bean 的屬性必須在 bean 的定義中或者是自動裝配中通過明確的屬性值在配置時來填充。如果受影響的 bean 屬性沒有被填充,那么容器就會拋出異 常;這就允許了急切而且明確的失敗,要避免 NullPointerException。我們推薦你放 置斷言到 bean 的類中,比如,放置到初始化方法中。當你在容器外部使用類時,這么來做 是強制那些所需的引用和值。
### 4.9.2 @Autowired 和@Inject
正如預期的那樣,你可以使用@Autowired 注解到“傳統的”setter 方法中: 注意在下面的示例中,JSR330 的@Inject 注解可以用于代替 Spring 的@Autowired。沒有必須的屬性,不像 Spring 的@Autowired 注解那樣,如果要注入的值是可選的話,要有一個 required 屬性來表示。如果你將 JSR330 的 JAR 包放置到類路徑下的話,這種行為就會自 動開啟。
```
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
```
你也可以將注解應用于任意名稱和/或多個參數的方法:
```
public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
```
你也可以將用于構造方法和字段:
```
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
```
也可以提供 ApplicationContext 中特定類型的所有 bean,通過添加注解到期望哪 種類型的數組的字段或者方法上:
```
public class MovieRecommender {
@Autowired
private MovieCatalog[] movieCatalogs;
// ...
}
```
相同地,也可以用于特定類型的集合:
```
public class MovieRecommender {
private Set<MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
```
甚至特定類型的 Map 也可以自動裝配,但是期望的鍵的類型是 String 的。Map 值會 包含所有期望類型的 bean,而鍵會包含對應 bean 的名字:
```
public class MovieRecommender {
private Map<String, MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
```
默認情況下,當出現零個候選 bean 的時候,自動裝配就會失敗;默認的行為是將被注解的方法,構造方法和字段作為需要的依賴關系。這種行為也可以通過下面這樣的做法來改變。
```
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired(required=false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
```
> 
> 注意
> 每一個類中僅有一個被注解方法可以標記為必須的,但是多個非必須的構造方法可 以被注解。在那種情況下,每個構造方法都要考慮到而且 Spring 使用依賴可以被滿足 的那個構造方法,那就是參數最多的那個構造方法。
@Autowired 需要的屬性推薦使用@Required 注解。所需的表示了屬性對于自動 裝配目的不是必須的,如果它不能被自動裝配,那么屬性就會忽略了。另一方面,
@Required 更健壯一些,它強制了由容器支持的各種方式的屬性設置。如果沒有注入任何值,就會拋出對應的異常。 你也可以針對我們熟知的解決依賴關系的接口來使用@Autowired:BeanFactory,ApplicationContext , Environment , ResourceLoader ,ApplicationEventPublisher 和 MessageSource。這些接口和它們的擴展接口,比 如 ConfigurableApplicationContext 或 ResourcePatternResolver 也會被自動解析,而不需要特殊設置的必要。
```
public class MovieRecommender {
@Autowired
private ApplicationContext context;
public MovieRecommender() {
}
// ...
}
```
> 
> 注意
> @Autowired , @Inject , @Resource 和 @Value 注 解 是 由 Spring 的 BeanPostProcessor 實現類來控制的,反過來告訴你你不能在 BeanPostProcessor 或 BeanFactoryPostProcessor 類型(任意之一)應用這些注解。這些類型必須明確地 通過 XML 或使用 Spring 的@Bean 方法來‘裝配’。
### 4.9.3 使用限定符來微調基于注解的自動裝配
因為通過類型的自動裝配可能導致多個候選者,那么在選擇過程中通常是需要更多的控 制的。達成這個目的的一種做法就是 Spring 的@Qualifier 注解。你可以用特定的參數來 關聯限定符的值,縮小類型的集合匹配,那么特定的 bean 就為每一個參數來選擇。最簡單 的情形,這可以是普通描述性的值:
> 
> 注意
> JSR 330 的@Qualifier 注解僅僅能作為元注解來用,而不像 Spring 的@Qualifier 可以 使用字符串屬性來在多個注入的候選者之間區別,并可以放在注解,類型,字段,方法,構 造方法和參數中。
```
public class MovieRecommender {
@Autowired
@Qualifier("main")
private MovieCatalog movieCatalog;
// ...
}
```
@Qualifier 注解也可以在獨立構造方法參數或方法參數中來指定:
```
public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(@Qualifier("main") MovieCatalog movieCatalog,CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
```
對應的 bean 的定義可以按如下所示。限定符值是“main”的 bean 會用限定了相同值 的構造方法參數來裝配。
```
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd http://www.springframework.org/schema/contex)t http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean class="example.SimpleMovieCatalog">
<qualifier value="main"/>
<!-- 注入這個bean需要的任何依賴 -->
</bean>
<bean class="example.SimpleMovieCatalog">
<qualifier value="action"/>
<!-- 注入這個bean需要的任何依賴 -->
</bean>
<bean id="movieRecommender" class="example.MovieRecommender"/>
</beans>
```
對于后備匹配,bean 名稱被認為是默認的限定符值。因此你可以使用 id 為“main”來 定義 bean,來替代嵌套的限定符元素,這也會達到相同的匹配結果。然而,盡管你使用這 種規約來通過名稱參照特定的 bean,@Autowired 從根本上來說就是關于類型驅動注入和可 選語義限定符的。這就是說限定符的值,即便有 bean 的名稱作為后備,通常在類型匹配時 也會縮小語義;它們不會在語義上表達對唯一 bean 的 id 的引用。好的限定符的值是“main” 或“EMEA”或“persistent”,特定組件的表達特性是和 bean 的 id 獨立的,在比如前面示例 之一的匿名 bean 的情況下它是可能自動被創建的。
限定符也可以用于類型集合,正如上面討論過的,比如 `Set<MovieCatalog>`。在這 種情況下,根據聲明的限定符,所有匹配的 bean 都會被注入到集合中。這就說明了限定符 不必是唯一的;它們只是構成了篩選條件。比如,你可以使用相同的限定符“action”來定 義多個 MovieCatalog bean;它們全部都會通過@Qualifier("action")注解注入到 `Set<MovieCatalog>`中。
> 
> 提示
> 如果你想通過名稱來表達注解驅動注入,主要是不使用@Autowired,即便在技術上來說能夠通過@Qualifier 值指向一個 bean 的名稱。相反 ,使用 JSR-250 的 @Resource 注解,在語義上定義了通過它的唯一名稱去確定一個具體的目標組件,聲 明的類型和匹配過程無關。
由于這種語義區別的特定后果,bean 本身被定義為集合或 map 類型,是不能通過 @Autowired 來進行注入的,因為類型匹配用于它們不太合適。對于這樣的 bean 使用 @Resource,通過唯一的名稱指向特定的集合或 map 類型的 bean。
@Autowired 可以用于字段,構造方法和多參數方法,在參數級允許通過限定符 注解縮小。相比之下,@Resource 僅支持字段和僅有一個參數的 bea n 屬性的 setter 方法。因此,如果你的注入目標是構造方法或多參數的方法,那么就堅持使用限定符。 你可以創建你自定義的限定符注解。只需定義一個注解并在你的定義中提供 @Qualifier 注解即可。 注意你可以以下面描述的方式來使用 JSR 330 的@Qualifier 注解,用于替換 Spring 的 @Qualifier 注解。如果在類路徑中有 JSR 330 的 jar 包,那么這種行為是自動開啟的。
```
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre { String value(); }
```
之后你可以在自動裝配的字段和參數上提供自定義的限定符:
```
public class MovieRecommender {
@Autowired
@Genre("Action")
private MovieCatalog actionCatalog;
private MovieCatalog comedyCatalog;
@Autowired
public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) {
this.comedyCatalog = comedyCatalog;
}
// ...
}
```
之后,為候選 bean 提供信息,你可以添加`<qualifier/>`標簽來作為`<bean/>`標簽的 子元素,然后指定 type 和 value 值來匹配你自定義的限定符注解。這種類型匹配是基于 注解類的完全限定名。否則,作為一種簡便的形式,如果沒有名稱沖突存在的風險,你可以 使用短類名。這兩種方法都會在下面的示例中來展示。
```
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean class="example.SimpleMovieCatalog">
<qualifier type="Genre" value="Action"/>
<!— 注入這個bean所需要的任何依賴 -->
</bean>
<bean class="example.SimpleMovieCatalog">
<qualifier type="example.Genre" value="Comedy"/>
<!— 注入這個bean所需要的任何依賴 -->
</bean>
<bean id="movieRecommender" class="example.MovieRecommender"/>
</beans>
```
在 4.10 節,“類路徑掃描和管理的組件”中,你會看到基于注解的替代,在 XML 中來 提供限定符元數據。特別是在 4.10.7 節,“使用注解提供限定符元數據”中。
在一些示例中,使用無值的注解就足夠了。這當注解服務于多個通用目的時是很有用的,
而且也可以用于集中不同類型的依賴關系。比如,當沒有因特網連接時,你可以提供脫機目 錄來由于搜索。首先定義簡單的注解:
```
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Offline {
}
```
之后將注解添加到要被自動裝配的字段或屬性上:
```
public class MovieRecommender {
@Autowired
@Offline
private MovieCatalog offlineCatalog;
// ...
}
```
現在來定義 bean 的限定符的 type:
```
<bean class="example.SimpleMovieCatalog">
<qualifier type="Offline"/>
<!— 注入這個bean所需要的任何依賴 -->
</bean>
```
你也可以定義自定義的限定符注解來接受命名屬性,除了或替代簡單的 value 屬性。 如果多個屬性值之后在要不自動裝配的字段或參數上來指定,那么要考慮 bean 的定義必須 匹配自動裝備候選者的所有屬性值。示例,考慮下面的注解定義:
```
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MovieQualifier { String genre();
Format format();
}
```
在本例中,Format 是枚舉類型:
```
public enum Format { VHS, DVD, BLURAY }
```
要自動裝配的字段使用自定義的限定符和包含 genre 和 format 兩個屬性的值來注解。
```
public class MovieRecommender {
@Autowired
@MovieQualifier(format=Format.VHS, genre="Action")
private MovieCatalog actionVhsCatalog;
@Autowired
@MovieQualifier(format=Format.VHS, genre="Comedy")
private MovieCatalog comedyVhsCatalog;
@Autowired
@MovieQualifier(format=Format.DVD, genre="Action")
private MovieCatalog actionDvdCatalog;
@Autowired
@MovieQualifier(format=Format.BLURAY, genre="Comedy")
private MovieCatalog comedyBluRayCatalog;
// ...
}
```
最后,bean 的定義應該包含匹配的限定符值。這個示例也展示了 bean 的元屬性可能用 于替代`<qualifier/>`子元素。如果可用,`<qualifier/>`和它的屬性優先,但是如果目 前沒有限定符,自動裝配機制就會在`<meta/>`標簽提供的值上失效,就像下面這個示例中的 最后兩個 bean。
```
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean class="example.SimpleMovieCatalog">
<qualifier type="MovieQualifier">
<attribute key="format" value="VHS"/>
<attribute key="genre" value="Action"/>
</qualifier>
<!— 注入這個bean所需要的任何依賴 -->
</bean>
<bean class="example.SimpleMovieCatalog">
<qualifier type="MovieQualifier">
<attribute key="format" value="VHS"/>
<attribute key="genre" value="Comedy"/>
</qualifier>
<!— 注入這個bean所需要的任何依賴 -->
</bean>
<bean class="example.SimpleMovieCatalog">
<meta key="format" value="DVD"/>
<meta key="genre" value="Action"/>
<!— 注入這個bean所需要的任何依賴 -->
</bean>
<bean class="example.SimpleMovieCatalog">
<meta key="format" value="BLURAY"/>
<meta key="genre" value="Comedy"/>
<!— 注入這個bean所需要的任何依賴 -->
</bean>
</beans>
```
### 4.9.4 CustomAutowireConfigurer
[CustomAutowireConfigurer](http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.html) 是 BeanFactoryPostProcessor 的一種,它使得 你可以注冊你自己定義的限定符注解類型,即便它們沒有使用 Spring 的@Qualifier 注解 也是可以的。
```
<bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAu
towireConfigurer">
<property name="customQualifierTypes">
<set>
<value>example.CustomQualifier</value>
</set>
</property>
</bean>
```
AutowireCandidateResolver 的特別實現類對基于 Java 版本的應用程序上下文激 活。在 Java 5 之前的版本中,限定符注解是不支持的,因此自動裝配候選者僅由每個 bean 定義中的 autowire-candidate 值來決 定,還有 在`<beans/>`元 素中的任 何可用的 default-autowire-candidates 模 式 也 是 可 以 的 。 在 Java 5 之 后 的 版 本 中 , @Qualifier 注解的存在還有任意使用 CustomAutowireConfigurer 注冊的自定義注解也將發揮作用。
不管 Java 的版本,當多個 bean 作為自動裝配的候選者,決定“主要”候選者的方式也 是相同的:如果候選者中一個 bean 的定義有 primary 屬性精確地設置為 true,那么它就會被選擇。
### 4.9.5 @Resource
Spring 也支持使用 JSR 250 的@Resource 注解在字段或 bean 屬性的 setter 方法上的注 入。這在 Java EE 5 和 6 中是一個通用的模式,比如在 JSF 1.2 中管理的 bean 或 JAX-WS 2.0 端點。Spring 也為其所管理的對象支持這種模式。
@Resource 使用名稱屬性,默認情況下 Spring 解釋這個值作為要注入的 bean 的名稱。
換句話說,如果遵循 by-name 語義,正如在這個示例所展示的:
```
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
```
如果沒有明確地指定名稱,那么默認的名稱就從字段名稱或 setter 方法中派生出來。以字段為例,它會選用字段名稱;以 setter 方法為例,它會選用 bean 的屬性名稱。所以下面 的示例中有名為“movieFinder”的 bean 通過 setter 方法來注入:
```
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
```
> 
> 注意
> 使用注解提供的名稱被感知 CommonAnnotationBeanPostProcessor 的 ApplicationContext 解析成 bean 的名稱。名稱可以通過 JNDI 方式來解析,只要你明確 地配置了 Spring 的 [SimpleJndiBeanFactory](http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/jndi/support/SimpleJndiBeanFactory.html)。然而,還是推薦你基于默認行為并僅使用 Spring 的 JNDI 查找能力來保存間接的水平。
在使用@Resource 并沒有 明確指 定名稱的 獨占情況 下,和 @Autowired 相似, @Resource 發現主要類型匹配,而不是特定名稱 bean 并解析了熟知的可解析的依賴關系: BeanFactory , ApplicationContext , ResourceLoader , ApplicationEventPublisher,MessageSource 和接口。
因 此 , 在 下 面 的 示 例 中 , customerPreferenceDao 字 段 首 先 尋 找 名 為 customerPreferenceDao 的 bean,之后回到匹配 CustomerPreferenceDao 的主類型。 “context”字段基于已知的可解析的依賴類型 ApplicationContext 注入。
```
public class MovieRecommender {
@Resource
private CustomerPreferenceDao customerPreferenceDao;
@Resource
private ApplicationContext context;
public MovieRecommender() {
}
// ...
}
```
### 4.9.6 @PostConstruct 和@PreDestroy
CommonAnnotationBeanPostProcessor 不但能識別@Resource 注解,而且還能 識別 JSR-250 生命周期注解。在 Spring 2.5 中引入,對這些注解的支持提供了在初始化回調( 4.6.1.1 節 ) 和 銷 毀 回 調 ( 4.6.1.2 節 ) 中 的 另 一 種 選 擇 。 只 要 CommonAnnotationBeanPostProcessor 在 Spring 的 ApplicationContext 中注冊, 一個攜帶這些注解之一的方法就同時被調用了,和 Spring 生命周期接口方法或明確地聲明回調方法相對應。在下面的示例中,在初始化后緩存會預先填充,在銷毀后會清理。
```
public class CachingMovieLister {
@PostConstruct
public void populateMovieCache() {
// 在初始化時填充movie cache...
}
@PreDestroy
public void clearMovieCache() {
// 在銷毀后清理movie cache...
}
}
```
> 
> 注意
> 關于組合多個生命周期機制影響的細節內容,請參考 4.6.1.4 節,“組合生命周期機制”。
- Spring 中文文檔 3.1
- 第一部分 Spring framework 概述
- 第 1 章 Spring Framework 介紹
- 1.1 依賴注入和控制反轉
- 1.2 模塊
- 1.3 使用方案
- 第二部分 Spring 3 的新特性
- 第 2 章 Spring 3.0 的新特性和增強
- 2.1 Java 5
- 2.2 改進的文檔
- 2.3 新的文章和教程
- 2.4 新的模塊組織方式和系統構建方式
- 2.5 新特性概述
- 第 3 章 Spring 3.1 的新特性和增強
- 3.1 新特性概述
- 第三部分 核心技術
- 第 4 章 IoC 容器
- 4.1 Spring IoC 容器和 bean 的介紹
- 4.2 容器概述
- 4.3 Bean 概述
- 4.4 依賴
- 4.5 Bean 的范圍
- 4.6 自定義 bean 的性質
- 4.7 Bean 定義的繼承
- 4.8 容器擴展點
- 4.9 基于注解的容器配置
- 4.10 類路徑掃描和管理的組件
- 4.11 使用 JSR 330 標準注解
- 4.12 基于 Java 的容器配置
- Hibernate 中文文檔 3.2
- 前言
- 1. 翻譯說明
- 2. 版權聲明
- 第 1 章 Hibernate入門
- 1.1. 前言
- 1.2. 第一部分 - 第一個Hibernate應用程序
- 1.2.1. 第一個class
- 1.2.2. 映射文件
- 1.2.3. Hibernate配置
- 1.2.4. 用Ant構建
- 1.2.5. 啟動和輔助類
- 1.2.6. 加載并存儲對象
- 1.3. 第二部分 - 關聯映射
- 1.3.1. 映射Person類
- 1.3.2. 單向Set-based的關聯
- 1.3.3. 使關聯工作
- 1.3.4. 值類型的集合
- 1.3.5. 雙向關聯
- 1.3.6. 使雙向連起來
- 1.4. 第三部分 - EventManager web應用程序
- 1.4.1. 編寫基本的servlet
- 1.4.2. 處理與渲染
- 1.4.3. 部署與測試
- 1.5. 總結
- 第 2 章 體系結構(Architecture)
- 2.1. 概況(Overview)
- 2.2. 實例狀態
- 2.3. JMX整合
- 2.4. 對JCA的支持
- 2.5. 上下文相關的(Contextual)Session
- 第 3 章 配置
- 3.1. 可編程的配置方式
- 3.2. 獲得SessionFactory
- 3.3. JDBC連接
- 3.4. 可選的配置屬性
- 3.4.1. SQL方言
- 3.4.2. 外連接抓取(Outer Join Fetching)
- 3.4.3. 二進制流 (Binary Streams)
- 3.4.4. 二級緩存與查詢緩存
- 3.4.5. 查詢語言中的替換
- 3.4.6. Hibernate的統計(statistics)機制
- 3.5. 日志
- 3.6. 實現NamingStrategy
- 3.7. XML配置文件
- 3.8. J2EE應用程序服務器的集成
- 3.8.1. 事務策略配置
- 3.8.2. JNDI綁定的SessionFactory
- 3.8.3. 在JTA環境下使用Current Session context (當前session上下文)管理
- 3.8.4. JMX部署
- 第 4 章 持久化類(Persistent Classes)
- 4.1. 一個簡單的POJO例子
- 4.1.1. 實現一個默認的(即無參數的)構造方法(constructor)
- 4.1.2. 提供一個標識屬性(identifier property)(可選)
- 4.1.3. 使用非final的類 (可選)
- 4.1.4. 為持久化字段聲明訪問器(accessors)和是否可變的標志(mutators)(可選)
- 4.2. 實現繼承(Inheritance)
- 4.3. 實現equals()和hashCode()
- 4.4. 動態模型(Dynamic models)
- 4.5. 元組片斷映射(Tuplizers)
- 第 5 章 對象/關系數據庫映射基礎(Basic O/R Mapping)
- 5.1. 映射定義(Mapping declaration)
- 5.1.1. Doctype
- 5.1.1.1. EntityResolver
- 5.1.2. hibernate-mapping
- 5.1.3. class
- 5.1.4. id
- 5.1.4.1. Generator
- 5.1.4.2. 高/低位算法(Hi/Lo Algorithm)
- 5.1.4.3. UUID算法(UUID Algorithm )
- 5.1.4.4. 標識字段和序列(Identity columns and Sequences)
- 5.1.4.5. 程序分配的標識符(Assigned Identifiers)
- 5.1.4.6. 觸發器實現的主鍵生成器(Primary keys assigned by triggers)
- 5.1.5. composite-id
- 5.1.6. 鑒別器(discriminator)
- 5.1.7. 版本(version)(可選)
- 5.1.8. timestamp (可選)
- 5.1.9. property
- 5.1.10. 多對一(many-to-one)
- 5.1.11. 一對一
- 5.1.12. 自然ID(natural-id)
- 5.1.13. 組件(component), 動態組件(dynamic-component)
- 5.1.14. properties
- 5.1.15. 子類(subclass)
- 5.1.16. 連接的子類(joined-subclass)
- 5.1.17. 聯合子類(union-subclass)
- 5.1.18. 連接(join)
- 5.1.19. 鍵(key)
- 5.1.20. 字段和規則元素(column and formula elements)
- 5.1.21. 引用(import)
- 5.1.22. any
- 5.2. Hibernate 的類型
- 5.2.1. 實體(Entities)和值(values)
- 5.2.2. 基本值類型
- 5.2.3. 自定義值類型
- 5.3. 多次映射同一個類
- 5.4. SQL中引號包圍的標識符
- 5.5. 其他元數據(Metadata)
- 5.5.1. 使用 XDoclet 標記
- 5.5.2. 使用 JDK 5.0 的注解(Annotation)
- 5.6. 數據庫生成屬性(Generated Properties)
- 5.7. 輔助數據庫對象(Auxiliary Database Objects)
- 第 6 章 集合類(Collections)映射
- 6.1. 持久化集合類(Persistent collections)
- 6.2. 集合映射( Collection mappings )
- 6.2.1. 集合外鍵(Collection foreign keys)
- 6.2.2. 集合元素(Collection elements)
- 6.2.3. 索引集合類(Indexed collections)
- 6.2.4. 值集合于多對多關聯(Collections of values and many-to-many associations)
- 6.2.5. 一對多關聯(One-to-many Associations)
- 6.3. 高級集合映射(Advanced collection mappings)
- 6.3.1. 有序集合(Sorted collections)
- 6.3.2. 雙向關聯(Bidirectional associations)
- 6.3.3. 雙向關聯,涉及有序集合類
- 6.3.4. 三重關聯(Ternary associations)
- 6.3.5. 使用&amp;lt;idbag&amp;gt;
- 6.4. 集合例子(Collection example)
- 第 7 章 關聯關系映射
- 7.1. 介紹
- 7.2. 單向關聯(Unidirectional associations)
- 7.2.1. 多對一(many to one)
- 7.2.2. 一對一(one to one)
- 7.2.3. 一對多(one to many)
- 7.3. 使用連接表的單向關聯(Unidirectional associations with join tables)
- 7.3.1. 一對多(one to many)
- 7.3.2. 多對一(many to one)
- 7.3.3. 一對一(one to one)
- 7.3.4. 多對多(many to many)
- 7.4. 雙向關聯(Bidirectional associations)
- 7.4.1. 一對多(one to many) / 多對一(many to one)
- 7.4.2. 一對一(one to one)
- 7.5. 使用連接表的雙向關聯(Bidirectional associations with join tables)
- 7.5.1. 一對多(one to many) /多對一( many to one)
- 7.5.2. 一對一(one to one)
- 7.5.3. 多對多(many to many)
- 7.6. 更復雜的關聯映射
- 第 8 章 組件(Component)映射
- 8.1. 依賴對象(Dependent objects)
- 8.2. 在集合中出現的依賴對象 (Collections of dependent objects)
- 8.3. 組件作為Map的索引(Components as Map indices )
- 8.4. 組件作為聯合標識符(Components as composite identifiers)
- 8.5. 動態組件 (Dynamic components)
- 第 9 章 繼承映射(Inheritance Mappings)
- 9.1. 三種策略
- 9.1.1. 每個類分層結構一張表(Table per class hierarchy)
- 9.1.2. 每個子類一張表(Table per subclass)
- 9.1.3. 每個子類一張表(Table per subclass),使用辨別標志(Discriminator)
- 9.1.4. 混合使用“每個類分層結構一張表”和“每個子類一張表”
- 9.1.5. 每個具體類一張表(Table per concrete class)
- 9.1.6. Table per concrete class, using implicit polymorphism
- 9.1.7. 隱式多態和其他繼承映射混合使用
- 9.2. 限制
- 第 10 章 與對象共事
- 10.1. Hibernate對象狀態(object states)
- 10.2. 使對象持久化
- 10.3. 裝載對象
- 10.4. 查詢
- 10.4.1. 執行查詢
- 10.4.1.1. 迭代式獲取結果(Iterating results)
- 10.4.1.2. 返回元組(tuples)的查詢
- 10.4.1.3. 標量(Scalar)結果
- 10.4.1.4. 綁定參數
- 10.4.1.5. 分頁
- 10.4.1.6. 可滾動遍歷(Scrollable iteration)
- 10.4.1.7. 外置命名查詢(Externalizing named queries)
- 10.4.2. 過濾集合
- 10.4.3. 條件查詢(Criteria queries)
- 10.4.4. 使用原生SQL的查詢
- 10.5. 修改持久對象
- 10.6. 修改脫管(Detached)對象
- 10.7. 自動狀態檢測
- 10.8. 刪除持久對象
- 10.9. 在兩個不同數據庫間復制對象
- 10.10. Session刷出(flush)
- 10.11. 傳播性持久化(transitive persistence)
- 10.12. 使用元數據
- 第 11 章 事務和并發
- 11.1. Session和事務范圍(transaction scope)
- 11.1.1. 操作單元(Unit of work)
- 11.1.2. 長對話
- 11.1.3. 關注對象標識(Considering object identity)
- 11.1.4. 常見問題
- 11.2. 數據庫事務聲明
- 11.2.1. 非托管環境
- 11.2.2. 使用JTA
- 11.2.3. 異常處理
- 11.2.4. 事務超時
- 11.3. 樂觀并發控制(Optimistic concurrency control)
- 11.3.1. 應用程序級別的版本檢查(Application version checking)
- 11.3.2. 擴展周期的session和自動版本化
- 11.3.3. 脫管對象(deatched object)和自動版本化
- 11.3.4. 定制自動版本化行為
- 11.4. 悲觀鎖定(Pessimistic Locking)
- 11.5. 連接釋放模式(Connection Release Modes)
- 第 12 章 攔截器與事件(Interceptors and events)
- 12.1. 攔截器(Interceptors)
- 12.2. 事件系統(Event system)
- 12.3. Hibernate的聲明式安全機制
- 第 13 章 批量處理(Batch processing)
- 13.1. 批量插入(Batch inserts)
- 13.2. 批量更新(Batch updates)
- 13.3. StatelessSession (無狀態session)接口
- 13.4. DML(數據操作語言)風格的操作(DML-style operations)
- 第 14 章 HQL: Hibernate查詢語言
- 14.1. 大小寫敏感性問題
- 14.2. from子句
- 14.3. 關聯(Association)與連接(Join)
- 14.4. join 語法的形式
- 14.5. select子句
- 14.6. 聚集函數
- 14.7. 多態查詢
- 14.8. where子句
- 14.9. 表達式
- 14.10. order by子句
- 14.11. group by子句
- 14.12. 子查詢
- 14.13. HQL示例
- 14.14. 批量的UPDATE和DELETE
- 14.15. 小技巧 & 小竅門
- 第 15 章 條件查詢(Criteria Queries)
- 15.1. 創建一個Criteria 實例
- 15.2. 限制結果集內容
- 15.3. 結果集排序
- 15.4. 關聯
- 15.5. 動態關聯抓取
- 15.6. 查詢示例
- 15.7. 投影(Projections)、聚合(aggregation)和分組(grouping)
- 15.8. 離線(detached)查詢和子查詢
- 15.9. 根據自然標識查詢(Queries by natural identifier)
- 第 16 章 Native SQL查詢
- 16.1. 使用SQLQuery
- 16.1.1. 標量查詢(Scalar queries)
- 16.1.2. 實體查詢(Entity queries)
- 16.1.3. 處理關聯和集合類(Handling associations and collections)
- 16.1.4. 返回多個實體(Returning multiple entities)
- 16.1.4.1. 別名和屬性引用(Alias and property references)
- 16.1.5. 返回非受管實體(Returning non-managed entities)
- 16.1.6. 處理繼承(Handling inheritance)
- 16.1.7. 參數(Parameters)
- 16.2. 命名SQL查詢
- 16.2.1. 使用return-property來明確地指定字段/別名
- 16.2.2. 使用存儲過程來查詢
- 16.2.2.1. 使用存儲過程的規則和限制
- 16.3. 定制SQL用來create,update和delete
- 16.4. 定制裝載SQL
- 第 17 章 過濾數據
- 17.1. Hibernate 過濾器(filters)
- 第 18 章 XML映射
- 18.1. 用XML數據進行工作
- 18.1.1. 指定同時映射XML和類
- 18.1.2. 只定義XML映射
- 18.2. XML映射元數據
- 18.3. 操作XML數據
- 第 19 章 提升性能
- 19.1. 抓取策略(Fetching strategies)
- 19.1.1. 操作延遲加載的關聯
- 19.1.2. 調整抓取策略(Tuning fetch strategies)
- 19.1.3. 單端關聯代理(Single-ended association proxies)
- 19.1.4. 實例化集合和代理(Initializing collections and proxies)
- 19.1.5. 使用批量抓取(Using batch fetching)
- 19.1.6. 使用子查詢抓取(Using subselect fetching)
- 19.1.7. 使用延遲屬性抓取(Using lazy property fetching)
- 19.2. 二級緩存(The Second Level Cache)
- 19.2.1. 緩存映射(Cache mappings)
- 19.2.2. 策略:只讀緩存(Strategy: read only)
- 19.2.3. 策略:讀/寫緩存(Strategy: read/write)
- 19.2.4. 策略:非嚴格讀/寫緩存(Strategy: nonstrict read/write)
- 19.2.5. 策略:事務緩存(transactional)
- 19.3. 管理緩存(Managing the caches)
- 19.4. 查詢緩存(The Query Cache)
- 19.5. 理解集合性能(Understanding Collection performance)
- 19.5.1. 分類(Taxonomy)
- 19.5.2. Lists, maps 和sets用于更新效率最高
- 19.5.3. Bag和list是反向集合類中效率最高的
- 19.5.4. 一次性刪除(One shot delete)
- 19.6. 監測性能(Monitoring performance)
- 19.6.1. 監測SessionFactory
- 19.6.2. 數據記錄(Metrics)
- 第 20 章 工具箱指南
- 20.1. Schema自動生成(Automatic schema generation)
- 20.1.1. 對schema定制化(Customizing the schema)
- 20.1.2. 運行該工具
- 20.1.3. 屬性(Properties)
- 20.1.4. 使用Ant(Using Ant)
- 20.1.5. 對schema的增量更新(Incremental schema updates)
- 20.1.6. 用Ant來增量更新schema(Using Ant for incremental schema updates)
- 20.1.7. Schema 校驗
- 20.1.8. 使用Ant進行schema校驗
- 第 21 章 示例:父子關系(Parent Child Relationships)
- 21.1. 關于collections需要注意的一點
- 21.2. 雙向的一對多關系(Bidirectional one-to-many)
- 21.3. 級聯生命周期(Cascading lifecycle)
- 21.4. 級聯與未保存值(Cascades and unsaved-value)
- 21.5. 結論
- 第 22 章 示例:Weblog 應用程序
- 22.1. 持久化類
- 22.2. Hibernate 映射
- 22.3. Hibernate 代碼
- 第 23 章 示例:復雜映射實例
- 23.1. Employer(雇主)/Employee(雇員)
- 23.2. Author(作家)/Work(作品)
- 23.3. Customer(客戶)/Order(訂單)/Product(產品)
- 23.4. 雜例
- 23.4.1. "Typed" one-to-one association
- 23.4.2. Composite key example
- 23.4.3. 共有組合鍵屬性的多對多(Many-to-many with shared composite key attribute)
- 23.4.4. Content based discrimination
- 23.4.5. Associations on alternate keys
- 第 24 章 最佳實踐(Best Practices)
- HttpClient 教程
- 前言
- 第一章 基礎
- 第二章 連接管理
- 第三章 HTTP狀態管理
- 第四章 HTTP認證
- 第五章 HTTP客戶端服務
- 第六章 高級主題
- Mybatis 中文文檔 3.4
- 參考文檔
- 簡介
- 入門
- XML 映射配置文件
- Mapper XML 文件
- 動態 SQL
- Java API
- SQL語句構建器類
- Logging
- 項目文檔
- 項目總體信息
- 訪問
- 提醒方法
- 項目依賴
- Dependency Information
- Overview
- 問題跟蹤
- 項目授權
- 項目郵件列表
- Project Plugin Management
- Project Build Plugins
- Project Report Plugins
- 團隊
- Web訪問
- 匿名訪問
- 開發者訪問
- 通過防火墻訪問
- 項目概要
- 生成報表
- MyBatis Generator 用戶手冊
- MyBatis Generator介紹
- MyBatis Generator新增功能
- MyBatis Generator 快速入門指南
- 運行 MyBatis Generator
- 從命令行運行 MyBatis Generator
- 使用Ant運行 MyBatis Generator
- 通過Maven運行 MyBatis Generator
- 使用Java運行 MyBatis Generator
- 運行 MyBatis Generator 后的任務
- Migrating from Ibator
- Migrating from Abator
- MyBatis Generator XML 配置參考
- &lt;classPathEntry&gt; 元素
- &lt;columnOverride&gt; 元素
- &lt;columnRenamingRule&gt; 元素
- &lt;commentGenerator&gt; 元素
- &lt;context&gt; 元素
- &lt;generatedKey&gt; 元素
- &lt;generatorConfiguration&gt; 元素
- &lt;ignoreColumn&gt; 元素
- &lt;javaClientGenerator&gt; 元素
- The &lt;javaModelGenerator&gt; Element
- The &lt;javaTypeResolver&gt; Element
- &lt;jdbcConnection&gt; 元素
- &lt;plugin&gt; 元素
- &lt;properties&gt; 元素
- &lt;property&gt; 元素
- &lt;sqlMapGenerator&gt; 元素
- &lt;table&gt; 元素
- 使用生成的對象
- JAVA實體對象
- SQL映射文件
- Java客戶端對象
- Example類使用說明
- 擴展Example類
- 使用注意事項
- DB2 使用注意事項
- MySql 使用注意事項
- Oracle 使用注意事項
- PostgreSQL 使用注意事項
- 參考資料
- 從源碼構建
- 擴展MyBatis Generator
- 開發插件
- 日志信息
- 提供的插件
- 設計理念
- Velocity 中文文檔
- 1. 關于
- 2. 什么是Velocity?
- 3. Velocity 可以做什么?
- 3.1. Mud Store 示例
- 4. Velocity模板語言(VTL): 介紹
- 5. Hello Velocity World!
- 6. 注釋
- 7. 引用
- 7.1. 變量Variables
- 7.2. 屬性
- 7.3. 方法
- 8. 形式引用符Formal Reference Notation
- 9. 安靜引用符Quiet Reference Notation
- 11. Case Substitution
- 12. 指令
- 12.1. #set
- 12.2. 字面字符串
- 12.3. 條件
- 12.3.1 If / ElseIf / Else
- 12.3.2 關系和邏輯操作符
- 12.4. 循環
- 12.4.1. Foreach 循環
- 12.5. 包含
- 12.6. 解析
- 12.7. 停止
- 12.10. 宏
- 12.10.1. Velocimacro 參數
- 12.10.2. Velocimacro 屬性
- 12.10.3. Velocimacro Trivia
- 13. Getting literal
- 13.1. 貨幣字符
- 13.2. 轉義 有效的 VTL 指令
- 13.3. 轉義 無效的 VTL 指令
- 14. VTL 格式化問題
- 15. 其它特征和雜項
- 15.1. 數學特征
- 15.2. 范圍操作符
- 15.3. 進階:轉義和!
- 15.4. Velocimacro 雜記
- 15.5. 字符串聯
- Google Guava官方教程(中文版)
- 1-基本工具
- 1.1-使用和避免null
- 1.2-前置條件
- 1.3-常見Object方法
- 1.4-排序: Guava強大的”流暢風格比較器”
- 1.5-Throwables:簡化異常和錯誤的傳播與檢查
- 2-集合
- 2.1-不可變集合
- 2.2-新集合類型
- 2.3-強大的集合工具類:java.util.Collections中未包含的集合工具
- 2.4-集合擴展工具類
- 3-緩存
- 4-函數式編程
- 5-并發
- 5.1-google Guava包的ListenableFuture解析
- 5.2-Google-Guava Concurrent包里的Service框架淺析
- 6-字符串處理:分割,連接,填充
- 7-原生類型
- 8-區間
- 9-I/O
- 10-散列
- 11-事件總線
- 12-數學運算
- 13-反射
- JFreeChart 開發者指南
- 1 簡介
- 1.1 什么是JFreeChart
- 1.2 使用文檔
- 1.3 感謝
- 1.4 建議
- 2 圖表實例
- 2.1 介紹
- 2.2 餅圖(Pie Charts)
- 2.3 直方條形圖(Bar Charts)
- 2.4 折線圖(Line Charts)
- 2.5 XY(散點圖)
- 2.6 時序圖
- 2.7 柱狀圖
- 2.8 面積圖
- 2.9 差異圖
- 2.10 梯形圖
- 2.11 甘特圖
- 2.12 多軸圖
- 2.13 復合/覆蓋圖
- 2.14 開發遠景
- 3 下載和安裝JFreeChart 1.0.6
- 3.1 簡介
- 3.2 下載
- 3.3 解包
- 3.4 運行演示實例
- 3.5 編譯源代碼
- 3.6 產生javadoc文檔
- 4 使用JFreeChart1.0.6
- 4.1 概述
- 4.2 創建第一個圖表
- 5 餅圖(Pie Charts)
- 5.1 簡介
- 5.2 創建一個簡單的餅圖(Pie Charts)
- 5.3 片區顏色
- 5.4 片區外廓
- 5.5 空置、零值和負值
- 5.6 片區和圖例標簽
- 5.7 “取出”某個片區
- 5.8 3D餅圖
- 5.9 多餅圖
- 5.10 實例講解
- 6 直方條形圖(Bar Charts)
- 6.1 簡介
- 6.2 創建一個直方條形圖
- 6.3 ChartFactory類
- 6.4 直方條形圖的簡單定制
- 6.5 定制外觀
- 6.6 示例代碼解讀
- 7 折線圖
- 7.1 簡介
- 7.2 使用categoryDataset數據集創建折線圖
- 7.3 使用XYDataset數據集創建折線圖
- 8 時序圖
- 8.1 簡介
- 8.2 創建時序圖
- 9 定制圖表(Customising Charts)
- 9.1 簡介
- 9.2 圖表屬性
- 9.3 圖區屬性
- 9.4 軸屬性
- 9.5 心得體會
- 10 動態圖(Dynamic Charts)
- 10.1 簡介
- 10.2 知識背景
- 10.3 實例應用
- 11 圖表工具條(Tooltips)
- 11.1 概述
- 11.2 創建圖表工具條
- 11.3 收集圖表工具條
- 11.4 顯示圖表工具條
- 11.5 隱藏圖表工具條
- 11.6 定制圖表工具條
- 12 圖表條目標簽(Item Label)
- 12.1 簡介
- 12.2 顯示條目標簽
- 12.3 條目標簽外觀
- 12.4 條目標簽位置
- 12.5 定制條目標簽文本
- 12.6 實例1
- 12.7 實例2
- 13 多軸和數據源圖表(Multi Axis and Dataset)
- 13.1 簡介
- 13.2 實例
- 13.3 建議和技巧
- 14 組合圖表(Combined Charts)
- 14.1 簡介
- 14.2 組合X種類圖區
- 14.3 組合Y種類圖區
- 14.4 組合X-XY圖區
- 14.5 組合Y-XY圖區
- 15 數據源和JDBC(Dataset And JDBC)
- 15.1 簡介
- 15.2 關于JDBC
- 15.3 樣本數據
- 15.4 PostgreSQL
- 15.5 JDBC驅動
- 15.6 應用演示
- 16 導出圖表為PDF格式
- 16.1 簡介
- 16.2 什么是Acrobat PDF
- 16.3 IText
- 16.4 Graphics2D
- 16.5 開始導出
- 16.6 實例應用
- 16.7 查看PDF 文件
- 16.8 Unicode字符問題
- 17 導出圖表為SVG格式
- 17.1 簡介
- 17.2 背景
- 17.3 實例代碼
- 18 Applet
- 18.1 簡介
- 18.2 問題
- 18.3 實例應用
- 19 Servlets
- 19.1 介紹
- 19.2 編寫一個簡單的Servlet應用
- 19.3 編譯實例Servlet
- 19.4 部署實例Servlet
- 19.5 在HMTL頁面種嵌入圖表
- 19.6 支持文件
- 19.7 部署Servlets
- 20 JFreeChart相關技術
- 20.1 簡介
- 20.2 X11/Headless Java
- 20.3 JSP
- 20.4 加載圖片
- 21 包
- 21.1 概述