亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Spring Java-based容器配置詳解

2024-07-13 10:12:55
字體:
來源:轉載
供稿:網友

裝Java-based的配置

使用 @Import 注解

跟在Spring XML文件中使用<import>元素添加模塊化的配置類似,@Import注解允許你加載其他配置類中的@Bean定義:

@Configurationpublic class ConfigA {	@Bean	  public A a() {		return new A();	}}@Configuration@Import(ConfigA.class)public class ConfigB {	@Bean	  public B b() {		return new B();	}}

組現在,當實例化上下文時,你只需要顯式的指定ConfigB,而不需要既提供ConfigA.class,又提供ConfigB.class:

public static void main(String[] args) {	ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);	// now both beans A and B will be available...	A a = ctx.getBean(A.class);	B b = ctx.getBean(B.class);}

這種方式簡化了容器的初始化,因為只需要處理一個類,而不是讓開發者記住構造期間的大量@Configuration類。

導入@Bean的依賴注入

上面的示例可以工作,但太簡單。在大多數實際的場景中,beans會依賴另一個跨配置類的bean。當使用XML時,這不是問題,因為不涉及到編譯,其中一個bean只需要聲明ref="someBean",剩下的交給Spring在容器初始化期間處理即可。當然,當使用@Configuration類時,Java編譯器對配置模式產生一些限制,對其他beans的引用必須是合法的java語法。

幸運的是,解決該問題是很容易的。正如我們已經討論的,@Bean可以有任意多個用來描述bean依賴的參數。讓我們探討一個更現實的場景,在這里將使用一些彼此依賴的@Configuration類:

@Configurationpublic class ServiceConfig {	@Bean	  public TransferService transferService(AccountRepository accountRepository) {		return new TransferServiceImpl(accountRepository);	}}@Configurationpublic class RepositoryConfig {	@Bean	  public AccountRepository accountRepository(DataSource dataSource) {		return new JdbcAccountRepository(dataSource);	}}@Configuration@Import({	ServiceConfig.class, RepositoryConfig.class})public class SystemTestConfig {	@Bean	  public DataSource dataSource() {		// return new DataSource	}}public static void main(String[] args) {	ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);	// everything wires up across configuration classes...	TransferService transferService = ctx.getBean(TransferService.class);	transferService.transfer(100.00, "A123", "C456");}

 

這里有另外的方法可以達到相同的效果。記住,@Configuration根本上只是容器中的另一個bean-這意味著它們可以像其他bean那樣充分利用@Autowired注入元數據。

注: 確保以這種方式注入的都是簡單類型的。@Configuration類在容器初始化時被處理的相當早,用這種方式強制注入依賴可能導致無法預料地過早初始化問題。只要有可能就采用上面示例中基于參數的注入方式。

@Configurationpublic class ServiceConfig {	@Autowired	  private AccountRepository accountRepository;	@Bean	  public TransferService transferService() {		return new TransferServiceImpl(accountRepository);	}}@Configurationpublic class RepositoryConfig {	@Autowired	  private DataSource dataSource;	@Bean	  public AccountRepository accountRepository() {		return new JdbcAccountRepository(dataSource);	}}@Configuration@Import({	ServiceConfig.class, RepositoryConfig.class})public class SystemTestConfig {	@Bean	  public DataSource dataSource() {		// return new DataSource	}}public static void main(String[] args) {	ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);	// everything wires up across configuration classes...	TransferService transferService = ctx.getBean(TransferService.class);	transferService.transfer(100.00, "A123", "C456");}

在上面的示例中,使用@Autowired工作的很好,并且提供了想要的模塊化,但要確切地指明自動注入的bean定義在哪聲明依舊有點模糊。例如,一個開發者正在查看ServiceConfig,那你怎么準確地知道@Autowired AccountRepository bean在哪聲明的?在代碼中并不明確,不過有時候這樣就行。記著Spring Tool Suite可以提供渲染圖的工具,這些圖展示了Spring Bean之間是怎么連起來的-這可能是你需要的。同時,你的Java IDE可以輕松的找到所有聲明和使用AccountRepository類型的bean,并為你快速展現返回該類型的@Bean方法位置。

如果你不能接受這種模糊性,并希望在你的IDE中可以從一個@Configuration類導航到另一個,那就考慮注入配置類本身:

@Configurationpublic class ServiceConfig {	@Autowired	  private RepositoryConfig repositoryConfig;	@Bean	  public TransferService transferService() {		// navigate 'through' the config class to the @Bean method!		return new TransferServiceImpl(repositoryConfig.accountRepository());	}}

在上面的解決方案中,我們可以很明確地知道AccountRepository定義的地方。然而,ServiceConfig現在緊緊地跟RepositoryConfig耦合了。這就是權衡。緊耦合在某種程度上可以通過使用基于接口或抽象類的@Configuration類來減輕??紤]以下內容:

@Configurationpublic class ServiceConfig {	@Autowired	  private RepositoryConfig repositoryConfig;	@Bean	  public TransferService transferService() {		return new TransferServiceImpl(repositoryConfig.accountRepository());	}}@Configurationpublic interface RepositoryConfig {	@Bean	  AccountRepository accountRepository();}@Configurationpublic class DefaultRepositoryConfig implements RepositoryConfig {	@Bean	  public AccountRepository accountRepository() {		return new JdbcAccountRepository(...);	}}@Configuration@Import({	ServiceConfig.class, DefaultRepositoryConfig.class}) // import the concrete config!public class SystemTestConfig {	@Bean	  public DataSource dataSource() {		// return DataSource	}}public static void main(String[] args) {	ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);	TransferService transferService = ctx.getBean(TransferService.class);	transferService.transfer(100.00, "A123", "C456");}

現在,ServiceConfig跟具體的DefaultRepositoryConfig類是松耦合的關系,并且內嵌的IDE工具依舊有用:它很容易為開發者獲取RepositoryConfig實現的類型層次。采用這種方式,導航@Configuration和它們的依賴就變得跟平常處理基于接口的代碼導航沒區別了。

有條件的包含@Configuration類或@Beans

基于任意的系統狀態,有條件地禁用一個完整的@Configuration類,甚至單獨的@Bean方法通常是很有用的。一個常見的示例是,當一個特定的profile在Spring Environment中啟用時,使用@Profile注解激活beans。

@Profile注解實際上實現了一個非常靈活的注解:@Conditional。@Conditional注解意味著在注冊@Bean之前,必須先咨詢指定的org.springframework.context.annotation.Condition實現。

Condition接口的實現者只需簡單地提供一個返回true或false的matches(…?)方法。例如,下面是@Profile注解采用的Condition實現:

@Overridepublic Boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {	if (context.getEnvironment() != null) {		// Read the @Profile annotation attributes		MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());		if (attrs != null) {			for (Object value : attrs.get("value")) {				if (context.getEnvironment().acceptsProfiles(((String[]) value))) {					return true;				}			}			return false;		}	}	return true;}

具體參考@Conditional javadocs。

結合Java和XML配置

Spring @Configuration類支持目的不是想要100%的替換Spring XML。一些設施,比如Spring XML命名空間仍舊是配置容器的完美方式。在XML很方便或必須的情況下,你有個選擇:采用”XML為中心”的方式實例化容器,比如ClassPathXmlApplicationContext,或使用AnnotationConfigApplicationContext以”Java為中心”的方式,并使用@ImportResource注解導入需要的XML。

在以”XML為中心”的情況下使用@Configuration類

從XML啟動Spring容器,以特設模式包含@Configuration類可能是個更可選的方式。例如,在一個已經存在的使用Spring XML的大型代碼庫中,遵循按需原則創建@Configuration,并從現有的XML文件中包括它們是非常容易的。下面你將找到在這樣的”XML為中心”的解決方案中使用@Configuration類的可選項。

記著@Configuration類本質上只是容器中的bean定義。在下面的示例中,我們創建了一個名稱為AppConfig的@Configuration類,并將它作為<bean/>定義包含到system-test-config.xml中。因為<context:annotation-config/>是開啟的,容器將會識別@Configuration注解,并正確地處理AppConfig中聲明的@Bean方法。

@Configurationpublic class AppConfig {	@Autowired	  private DataSource dataSource;	@Bean	  public AccountRepository accountRepository() {		return new JdbcAccountRepository(dataSource);	}	@Bean	  public TransferService transferService() {		return new TransferService(accountRepository());	}}

ystem-test-config.xml如下:

<beans>  <!-- enable processing of annotations such as @Autowired and @Configuration -->  <context:annotation-config/>  <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>  <bean class="com.acme.AppConfig"/>  <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">    <property name="url" value="${jdbc.url}"/>    <property name="username" value="${jdbc.username}"/>    <property name="password" value="${jdbc.password}"/>  </bean></beans>

jdbc.properties如下:

jdbc.propertiesjdbc.url=jdbc:hsqldb:hsql://localhost/xdbjdbc.username=sajdbc.password=

main方法如下:

public static void main(String[] args) {  ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml");  TransferService transferService = ctx.getBean(TransferService.class);  // ...}

: 在上面的system-test-config.xml中,AppConfig<bean/>沒有聲明一個id元素。如果沒有bean引用它,那就沒有必要指定id元素,否則就要通過name從容器獲取bean(name對應bean定義中聲明的id)。DataSource也一樣-它只是通過類型自動注入(autowired by type),所以并不需要顯式的分配一個bean id。

由于@Configuration被@Component元注解了(被注解注解,很拗口),所以被@Configuration注解的類自動成為組件掃描(component scanning)的候選者。同樣使用上面的場景,我們可以重新定義system-test-config.xml來充分利用組件掃描。注意在這個示例中,我們不需要明確聲明<context:annotation-config/>,因為<context:component-scan/>啟用了同樣的功能。

system-test-config.xml如下:

<beans>  <!-- picks up and registers AppConfig as a bean definition -->  <context:component-scan base-package="com.acme"/>  <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>  <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">    <property name="url" value="${jdbc.url}"/>    <property name="username" value="${jdbc.username}"/>    <property name="password" value="${jdbc.password}"/>  </bean></beans>

在@Configuration”類為中心”的情況下使用@ImportResourcedaoru導入XML

在將@Configuration類作為配置容器的主要機制的應用中,仍舊存在對XML的需求。在那些場景中,可以使用@ImportResource,并定義所需的XML。這樣做可以實現以”Java為中心”的方式配置容器,并保留最低限度的XML。

@Configuration@ImportResource("classpath:/com/acme/properties-config.xml")public class AppConfig {	@Value("${jdbc.url}")	  private String url;	@Value("${jdbc.username}")	  private String username;	@Value("${jdbc.password}")	  private String password;	@Bean	  public DataSource dataSource() {		return new DriverManagerDataSource(url, username, password);	}}

properties-config.xml如下:

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

jdbc.properties如下:

jdbc.url=jdbc:hsqldb:hsql://localhost/xdbjdbc.username=sajdbc.password=

main方法如下:

public static void main(String[] args) {  ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);  TransferService transferService = ctx.getBean(TransferService.class);  // ...}

總結

以上就是本文關于Spring Java-based容器配置詳解的全部內容,希望對大家有所幫助。有不足之處,歡迎留言指正。感謝朋友們對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美与黑人午夜性猛交久久久| 国产视频在线观看一区二区| 日韩精品免费在线| 欧美日韩国产一区二区| 精品久久久久久电影| 欧美激情在线狂野欧美精品| 国产成人av在线| 欧美最猛黑人xxxx黑人猛叫黄| 91精品国产91久久久久久吃药| 亚洲一区二区三区乱码aⅴ蜜桃女| 中文字幕欧美国内| 日韩精品中文字幕在线观看| 美女999久久久精品视频| 成人444kkkk在线观看| 日韩高清免费观看| 久久精品国产免费观看| 亚洲国产又黄又爽女人高潮的| 久久影院资源网| 91大神在线播放精品| 久久久成人的性感天堂| 亚洲国产精品久久91精品| 国产成人亚洲综合91| 伊是香蕉大人久久| 欧洲亚洲女同hd| 51精品国产黑色丝袜高跟鞋| 亚洲一区av在线播放| 亚洲自拍欧美色图| 久久久国产精品x99av| 久久91精品国产91久久久| 欧美日韩性生活视频| 国产视频久久久久久久| 日韩影视在线观看| 久久成人精品电影| 91精品中文在线| 国产精品专区第二| 成人在线小视频| 这里只有精品视频| 成人免费观看网址| 日韩中文在线不卡| 国内精品久久久久久| 久久久久这里只有精品| 亚洲欧美国产制服动漫| 欧美成人午夜激情在线| 久久综合五月天| 欧美日韩精品在线视频| 欧美日韩国产成人高清视频| 中文字幕欧美精品在线| 欧美日韩国产在线播放| 国产97在线观看| 福利一区视频在线观看| 国产日韩精品视频| 亚洲成人黄色在线观看| 一区二区三区视频观看| www.日本久久久久com.| 51视频国产精品一区二区| 尤物精品国产第一福利三区| 亚洲欧洲av一区二区| 久久激情五月丁香伊人| 红桃视频成人在线观看| 国产91免费看片| 亚洲影视中文字幕| 欧美洲成人男女午夜视频| 亚洲国产精品va在线看黑人| 欧美一区二粉嫩精品国产一线天| 精品亚洲国产视频| 91理论片午午论夜理片久久| 91久久久久久| 亚洲一区二区少妇| 中文字幕亚洲精品| 在线视频欧美日韩| 精品福利免费观看| 亚洲人成伊人成综合网久久久| 精品国偷自产在线视频99| 精品偷拍各种wc美女嘘嘘| 啊v视频在线一区二区三区| 欧美激情网友自拍| 日本免费久久高清视频| 亚洲白虎美女被爆操| 91chinesevideo永久地址| 中文字幕亚洲综合久久筱田步美| 亚洲一区美女视频在线观看免费| 神马久久久久久| 亚洲va欧美va国产综合剧情| 亚洲精品99久久久久中文字幕| 亚洲欧美激情一区| 91国产精品视频在线| 国产亚洲欧洲在线| 97免费视频在线播放| 色婷婷亚洲mv天堂mv在影片| 97欧美精品一区二区三区| 久精品免费视频| 国产极品精品在线观看| 亚洲精品在线不卡| 成人黄色影片在线| 日韩成人高清在线| 亚洲美女黄色片| 欧美一级高清免费播放| 欧美精品videos另类日本| 亚洲国产成人精品电影| 欧美日韩国产一区二区| 国产精品自拍视频| 97视频在线观看播放| 久久成人精品视频| 亚洲大尺度美女在线| 伊人久久五月天| 国产精品视频26uuu| 亚洲午夜小视频| 黑人极品videos精品欧美裸| 国产精品揄拍一区二区| 色妞在线综合亚洲欧美| 欧美激情精品久久久久久变态| 欧美三级xxx| 久久亚洲私人国产精品va| 国产精选久久久久久| 国产精品久久久久久久久久尿| 国产精品福利在线| 久久av在线播放| 亚洲久久久久久久久久| 日韩美女激情视频| 人人澡人人澡人人看欧美| 97在线视频免费| 国产精品嫩草影院久久久| 亚洲国内高清视频| 亚洲精品电影网在线观看| 国产精品久久久久久av| 亚洲精品98久久久久久中文字幕| 日韩69视频在线观看| 亚洲欧美精品伊人久久| 日韩精品在线视频| 国产成人鲁鲁免费视频a| 91精品久久久久久久久久另类| 欧美xxxx做受欧美| 91国语精品自产拍在线观看性色| 欧美俄罗斯性视频| 美女av一区二区三区| 国产欧美亚洲精品| 亚洲国产精品大全| 国产精品丝袜一区二区三区| 国产成人精品视频| 91精品免费看| 日韩av综合网| 热门国产精品亚洲第一区在线| 日韩av在线不卡| 欧美日韩国产在线| 国产精品自拍偷拍视频| 久久久国产精品亚洲一区| 麻豆乱码国产一区二区三区| 国产精品678| 91中文在线视频| 精品精品国产国产自在线| 亚洲a级在线播放观看| 高潮白浆女日韩av免费看| 97香蕉超级碰碰久久免费软件| 亚洲视频第一页| 久精品免费视频| 亚洲欧美日本伦理| 久久久最新网址| 丝袜亚洲另类欧美重口| 国内精久久久久久久久久人| 成人精品久久久| 亚洲国产成人精品一区二区| 超碰日本道色综合久久综合| 日韩中文字幕视频| 欧美日韩国产中字|