国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Java-based容器配置詳解

Spring Java-based容器配置詳解

2021-01-18 09:50JavaDynamic Java教程

這篇文章主要介紹了Spring Java-based容器配置詳解,涉及注解和@Configuration類以及@Beans的相關知識,具有一定參考價值,需要的朋友可以了解。

Java-based的配置

使用 @Import 注解

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public 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:

?
1
2
3
4
5
6
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類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Configuration
public class ServiceConfig {
    @Bean
      public TransferService transferService(AccountRepository accountRepository) {
        return new TransferServiceImpl(accountRepository);
    }
}
@Configuration
public 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類在容器初始化時被處理的相當早,用這種方式強制注入依賴可能導致無法預料地過早初始化問題。只要有可能就采用上面示例中基于參數的注入方式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Configuration
public class ServiceConfig {
    @Autowired
      private AccountRepository accountRepository;
    @Bean
      public TransferService transferService() {
        return new TransferServiceImpl(accountRepository);
    }
}
@Configuration
public 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類導航到另一個,那就考慮注入配置類本身:

?
1
2
3
4
5
6
7
8
9
10
@Configuration
public 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類來減輕??紤]以下內容:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Configuration
public class ServiceConfig {
    @Autowired
      private RepositoryConfig repositoryConfig;
    @Bean
      public TransferService transferService() {
        return new TransferServiceImpl(repositoryConfig.accountRepository());
    }
}
@Configuration
public interface RepositoryConfig {
    @Bean
      AccountRepository accountRepository();
}
@Configuration
public 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實現:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public 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方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public 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如下:

?
1
2
3
4
5
6
7
8
9
10
11
<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如下:

?
1
2
3
4
jdbc.properties
jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
jdbc.username=sa
jdbc.password=

main方法如下:

?
1
2
3
4
5
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如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
<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。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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如下:

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

jdbc.properties如下:

?
1
2
3
jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
jdbc.username=sa
jdbc.password=

main方法如下:

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

總結

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

原文鏈接:http://blog.csdn.net/qbg19881206/article/details/46740097

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲精品一二区 | 免费自拍偷拍视频 | 99久色| 国产高清无密码一区二区三区 | 久久国产精品一区二区 | 日韩av免费在线观看 | 成年人视频在线观看免费 | www中文在线观看 | 求av网址 | 久久99精品久久久久久琪琪 | 日本激情网 | 91免费在线视频观看 | av在线免费观看网址 | 精品一区二区视频 | 国产成人一区二区 | 色婷婷综合网 | 国产美女在线播放 | 一本一道久久久a久久久精品91 | 最新电影在线高清免费完整观看视频 | 国产主播福利 | 亚洲成人精品在线 | 91.成人天堂一区 | 久久噜噜噜精品国产亚洲综合 | 日韩高清中文字幕 | 久久永久视频 | 日韩av中文 | 中文字幕在线观看日本 | 草久久久 | 日韩一二三| 欧美一区二区大片 | 在线看的毛片 | 亚洲情av| 黄毛片 | 国产精品久久99 | 国产精品国产a级 | 欧美日一区 | 亚洲欧美日韩在线一区二区三区 | 在线观看精品91福利 | 精品综合 | 日韩国产| 久久中文字幕一区二区三区 |