日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一文了解和SpringBean有關(guān)的那些注解

隨著Spring的流行,我們經(jīng)歷過基于XML-Based 的配置,隨著SpringBoot的流行,我們逐漸使用基于注解的配置替換掉了基于XML-Based的配置,那么你知道基于注解的配置的基礎(chǔ)組件都是什么嗎?都包括哪些要素?那么本節(jié)就來探討一下。注:本篇文章更多的是討論Spring基于注解的配置一覽,具體的技術(shù)可能沒有那么深,請各位大佬見諒。

探討主題:

  • 基礎(chǔ)概念:@Bean 和 @Configuration
  • 使用AnnotationConfigApplicationContext 實例化Spring容器
  • 使用@Bean 注解
  • 使用@Configuration 注解
  • 編寫基于Java的配置
  • Bean定義配置文件
  • PropertySource 抽象類
  • 使用@PropertySource
  • 占位符的聲明

基礎(chǔ)概念:@Bean 和 @Configuration

Spring中新的概念是支持@Bean注解 和 @Configuration 注解的類。@Bean 注解用來表明一個方法實例化,配置并且通過IOC容器初始化并管理一個新的對象。@Bean注解就等同于XML-Based中的 標簽,并且扮演了相同的作用。你可以使用基于注解的配置@Bean 和 @Component,然而他們都用在@Configuration配置類中。

使用@Configuration 注解的主要作用是作為bean定義的類,進一步來說,@Configuration注解的類允許通過調(diào)用同類中的其他@Bean標注的方法來定義bean之間依賴關(guān)系。如下所示:

新建一個maven項目(我一般都直接創(chuàng)建SpringBoot項目,比較省事),創(chuàng)建AppConfig,MyService,MyServiceImpl類,代碼如下:

 
 
 
 
  1. @Configuration 
  2. public class AppConfig { 
  3.  
  4.     @Bean 
  5.     public MyService myService(){ 
  6.         return new MyServiceImpl(); 
  7.     } 
  8.  
  9. public interface MyService {} 
  10. public class MyServiceImpl implements MyService {} 

上述的依賴關(guān)系等同于XML-Based:

 
 
 
 
  1.  
  2.      
  3.  

使用AnnotationConfigApplicationContext 實例化Spring容器

AnnotationConfigApplicationContext 基于注解的上下文是Spring3.0 新添加的注解,它是ApplicationContext的一個具體實現(xiàn),它可以接收@Configuration注解的類作為輸入?yún)?shù),還能接收使用JSR-330元注解的普通@Component類。

當(dāng)提供了@Configuration 類作為輸入?yún)?shù)時,@Configuration類就會注冊作為bean的定義信息并且所有聲明@Bean的方法也都會作為bean的定義信息。

當(dāng)提供@Component和JSR-330 聲明的類時,他們都會注冊作為bean的定義信息,并且假設(shè)在必要時在這些類中使用諸如@Autowired或@Inject之類的注解

簡單的構(gòu)造

在某些基于XML-Based的配置,我們想獲取上下文容器使用ClassPathXmlApplicationContext,現(xiàn)在你能夠使用@Configuration 類來實例化AnnotationConfigApplicationContext。

在MyService中添加一個printMessage()方法,實現(xiàn)類實現(xiàn)對應(yīng)的方法。新建測試類進行測試

 
 
 
 
  1. public class ApplicationTests { 
  2.  
  3.     public static void main(String[] args) { 
  4.         ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); 
  5.         MyService service = context.getBean(MyService.class); 
  6.           // printMessage() 輸出something... 
  7.         service.printMessage(); 
  8.     } 

如前所述,AnnotationConfigApplicationContext不僅限于使用@Configuration類。任何@Component或JSR-330帶注釋的類都可以作為輸入提供給構(gòu)造函數(shù),如下例所示

 
 
 
 
  1. public class ApplicationTests { 
  2.  
  3.     public static void main(String[] args) { 
  4.         ApplicationContext context = new AnnotationConfigApplicationContext(MyServiceImpl.class,Dependency1.class,Dependency2.class); 
  5.         MyService myService = context.getBean(MyService.class); 
  6.         myService.printMessage(); 
  7.     } 

使用register注冊IOC容器

你可以實例化AnnotationConfigApplicationContext通過使用無參數(shù)的構(gòu)造器并且使用register方法進行注冊,它和AnnotationConfigApplicationContext帶參數(shù)的構(gòu)造器起到的效果相同。

 
 
 
 
  1. public class ApplicationTests { 
  2.  
  3.     public static void main(String[] args) { 
  4.         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
  5.         ctx.register(AppConfig.class, OtherConfig.class); 
  6.         ctx.register(AdditionalConfig.class); 
  7.         ctx.refresh(); 
  8.         MyService myService = ctx.getBean(MyService.class); 
  9.         System.out.println(ctx.getBean(OtherConfig.class)); 
  10.         System.out.println(ctx.getBean(AdditionalConfig.class)); 
  11.         myService.printMessage(); 
  12.     } 

OtherConfig.class 和 AdditionalConfig.class 是使用@Component 標注的類。

允許scan()方法進行組件掃描

為了允許組件進行掃描,需要在@Configuration配置類添加@ComponentScan()注解,改造之前的AdditionalConfig類,如下:

 
 
 
 
  1. @Configuration 
  2. @ComponentScan(basePackages = "com.spring.annotation.config") 
  3. public class AdditionalConfig {} 

@ComponentScan指定了基礎(chǔ)掃描包位于com.spring.annotation.config下,所有位于該包范圍內(nèi)的bean都會被注冊進來,交由Spring管理。它就等同于基于XML-Based的注解:

 
 
 
 
  1.  
  2.      
  3.  

AnnotationConfigApplicationContext中的scan()方法以允許相同的組件掃描功能,如以下示例所示:

 
 
 
 
  1. public static void main(String[] args) { 
  2.   AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
  3.   ctx.scan("com.spring.annotation"); 
  4.   ctx.refresh(); 
  5.   MyService myService = ctx.getBean(MyService.class); 

為什么說@Configuration用法和@Component都能夠標注配置類?因為@Configuration的元注解就是@Component。

 
 
 
 
  1. @Target({ElementType.TYPE}) 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. @Documented 
  4. @Component 
  5. public @interface Configuration { 
  6. String value() default ""; 

使用AnnotationConfigWebApplicationContext支持web容器

AnnotationConfigApplicationContext的一個WebApplicationContext的變化是使用AnnotationConfigWebApplicationContext。配置Spring ContextLoaderListener的servlet監(jiān)聽器,Spring MVC的DispatcherServlet等時,可以使用此實現(xiàn)。以下web.xml代碼段配置典型的Spring MVC Web應(yīng)用程序(請注意context-param和init-param的使用)

 
 
 
 
  1.  
  2.        
  3.      
  4.         contextClass 
  5.          
  6.             org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
  7.          
  8.      
  9.  
  10.        
  11.      
  12.         contextConfigLocation 
  13.         com.spring.annotation.config.AdditionalConfig 
  14.      
  15.  
  16.        
  17.      
  18.         org.springframework.web.context.ContextLoaderListener 
  19.      
  20.  
  21.        
  22.      
  23.         dispatcher 
  24.         org.springframework.web.servlet.DispatcherServlet 
  25.          
  26.          
  27.             contextClass 
  28.              
  29.                 org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
  30.              
  31.          
  32.          
  33.          
  34.             contextConfigLocation 
  35.             com.spring.annotation.config.MvcConfig 
  36.          
  37.      
  38.  
  39.      
  40.      
  41.         dispatcher 
  42.         /app/* 
  43.      
  44.  

使用@Bean注解

@Bean 注解是一個方法級別的注解,能夠替換XML-Based中的標簽,@Bean注解同樣支持標簽支持的屬性,像是 init-method, destroy-method, autowiring。

定義一個Bean

與基礎(chǔ)概念中Bean的定義相同,讀者可以參考基礎(chǔ)概念部分進行了解,我們不在此再進行探討。

Bean的依賴

@Bean 注解可以有任意數(shù)量的參數(shù)來構(gòu)建其依賴項,例如

 
 
 
 
  1. public class MyService { 
  2.     private final MyRepository myRepository; 
  3.     public MyService(MyRepository myRepository) { 
  4.         this.myRepository = myRepository; 
  5.     } 
  6.     public String generateSomeString() { 
  7.         return myRepository.findString() + "-from-MyService"; 
  8.     } 
  9.  
  10. @Configuration 
  11. class MyConfiguration { 
  12.     @Bean 
  13.     public MyService myService() { 
  14.         return new MyService(myRepository()); 
  15.     } 
  16.     @Bean 
  17.     public MyRepository myRepository() { 
  18.         return new MyRepository(); 
  19.     } 
  20.  
  21. public class MyRepository { 
  22.     public String findString() { 
  23.         return "some-string"; 
  24.     } 

接受生命周期回調(diào)

任何使用@Bean的注解都支持生命周期的回調(diào),使用JSR-220提供的@PostConstruct和@PreDestory注解來實現(xiàn)。如果bean實現(xiàn)了InitializingBean,DisposableBean或者Lifecycle接口,他們的方法會由IOC容器回調(diào)。一些以Aware的實現(xiàn)接口(像是BeanFactoryAware,BeanNameAware, MessageSourceAware, ApplicationContextAware等)也支持回調(diào)。

@Bean注解支持特定的初始化和銷毀方法,就像XML-Based中的init-method和 destory-method中的bean屬性,下面這個例子證實了這一點

 
 
 
 
  1. @Configuration 
  2. public class AppConfig { 
  3.  
  4.     @Bean(initMethod = "init") 
  5.     public BeanOne beanOne(){ 
  6.         return new BeanOne(); 
  7.     } 
  8.  
  9.     @Bean(destroyMethod = "cleanup") 
  10.     public BeanTwo beanTwo(){ 
  11.         return new BeanTwo(); 
  12.     } 
  13.  
  14. class BeanOne { 
  15.     public void init(){} 
  16.  
  17. class BeanTwo { 
  18.     public void cleanup(){} 

對于上面的例子,也可以手動調(diào)用init()方法,與上面的initMethod 方法等效

 
 
 
 
  1. @Bean 
  2. public BeanOne beanOne(){ 
  3.   BeanOne beanOne = new BeanOne(); 
  4.   beanOne.init(); 
  5.   return beanOne; 

當(dāng)你直接使用Java開發(fā)時,你可以使用對象執(zhí)行任何操作,并且不必總是依賴于容器生命周期。

Bean的作用范圍

Spring包括@Scope注解能夠讓你指定Bean的作用范圍,Bean的Scope默認是單例的,也就是說@Bean標注的對象在IOC的容器中只有一個。你可以重寫@Scope的作用范圍,下面的例子說明了這一點,修改OtherConfig如下

 
 
 
 
  1. @Configuration 
  2. public class OtherConfig { 
  3.  
  4.     @Bean 
  5.     @Scope("prototype") 
  6.     public Dependency1 dependency1(){ 
  7.         return new Dependency1(); 
  8.     } 

每次嘗試獲取dependency1這個對象的時候都會重新生成一個新的對象實例。下面是Scope的作用范圍和解釋:

@Scope和Scoped-proxy

Spring提供了一種通過scoped proxies與scoped依賴一起作用的方式。最簡單的在XML環(huán)境中創(chuàng)建代理的方式是通過 標簽。使用@Scope注解為在Java中配置bean提供了與proxyMode屬性相同的功能。默認是不需要代理的(ScopedProxyMode.NO),但是你需要指定ScopedProxyMode.TARGET_CLASS或者ScopedProxyMode.INTERFACES。

自定義Bean名稱

默認的情況下,配置類通過@Bean配置的默認名稱(方法名***個字母小寫)進行注冊和使用,但是你可以更換@Bean的name為你想指定的名稱。修改AdditionalConfig 類

 
 
 
 
  1. @Configuration 
  2. //@ComponentScan(basePackages = "com.spring.annotation.config") 
  3. public class AdditionalConfig { 
  4.  
  5.     @Bean(name = "default") 
  6.     public Dependency2 dependency2(){ 
  7.         return new Dependency2(); 
  8.     } 

Bean的別名

有時候需要為單例的bean提供多個名稱,也叫做Bean的別名。Bean注解的name屬性接收一個Array數(shù)組。下面這個例子證實了這一點:

 
 
 
 
  1. @Configuration 
  2. public class OtherConfig { 
  3.  
  4. //    @Bean 
  5. //    @Scope("prototype") 
  6. //    public Dependency1 dependency1(){ 
  7. //        return new Dependency1(); 
  8. //    } 
  9.  
  10.         @Bean({"dataSource", "dataSourceA", "dataSourceB"}) 
  11.     public DataSource dataSource(){ 
  12.             return null; 
  13.     } 

Bean的描述

有時,提供更詳細的bean描述信息會很有幫助(但是開發(fā)很少使用到)。為了增加一個對@Bean的描述,你需要使用到@Description注解

 
 
 
 
  1. @Configuration 
  2. public class OtherConfig { 
  3.  
  4. //    @Bean 
  5. //    @Scope("prototype") 
  6. //    public Dependency1 dependency1(){ 
  7. //        return new Dependency1(); 
  8. //    } 
  9.  
  10. //    @Bean({"dataSource", "dataSourceA", "dataSourceB"}) 
  11. //    public DataSource dataSource(){ 
  12. //        return null; 
  13. //    } 
  14.  
  15.     @Bean 
  16.     @Description("此方法的bean名稱為dependency1") 
  17.     public Dependency1 dependency1(){ 
  18.         return new Dependency1(); 
  19.     } 

使用@Configuration注解

已經(jīng)把@Configuration的注解說明的比較詳細了。

組成Java-Based環(huán)境配置的條件

Spring基于注解的配置能夠允許你自定義注解,同時能夠降低配置的復(fù)雜性。

使用@Import注解

就像在Spring XML文件中使用元素來幫助模塊化配置一樣,@Import 注解允許從另一個配置類加載@Bean定義,如下所示

 
 
 
 
  1. @Configuration 
  2. public class ConfigA { 
  3.  
  4.     @Bean 
  5.     public A a(){ 
  6.         return new A(); 
  7.     } 
  8.  
  9. @Configuration 
  10. @Import(ConfigA.class) 
  11. public class ConfigB { 
  12.  
  13.     @Bean 
  14.     public B b(){ 
  15.         return new B(); 
  16.     } 

現(xiàn)在,在實例化上下文時,不需要同時指定ConfigA.class 和 ConfigB.class ,只需要顯示提供ConfigB

 
 
 
 
  1. public static void main(String[] args) { 
  2.     ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class); 
  3.  
  4.     A a = ctx.getBean(A.class); 
  5.     B b = ctx.getBean(B.class); 

這種方法簡化了容器實例化,因為只需要處理一個類,而不是要求你在構(gòu)造期間記住可能大量的@Configuration類

有選擇性的包含@Configuration 類和@Bean 方法

選擇性的允許或者禁止@Configuration注解的類和@Bean注解的方法是很有用的,基于一些任意系統(tǒng)狀態(tài)。一個常見的例子是只有在Spring環(huán)境中啟用了特定的配置文件時才使用@Profile注釋激活bean。

@Profile注解也實現(xiàn)了更靈活的注解@Conditional,@Conditional 注解表明在注冊@Bean 之前應(yīng)參考特定的Condition實現(xiàn)。

實現(xiàn)Condition接口就會提供一個matched方法返回true或者false

更多關(guān)于@Conditional 的示例,請參考https://www.cnblogs.com/cxuanBlog/p/10960575.html

結(jié)合Java與XML配置

Spring @Configuration類能夠100%替換XML配置,但一些工具(如XML命名空間)仍舊是配置容器的***方法,在這種背景下,使用XML使很方便的而且使剛需了。你有兩個選擇:使用以XML配置實例化容器為中心,例如:ClassPathXmlApplicationContext導(dǎo)入XML或者實例化以Java配置為中心的AnnotationConfigApplicationContext并提供ImportResource注解導(dǎo)入需要的XML配置。

將@Configuration聲明為普通的bean元素

請記住,@Configuration類存放的是容器中的bean定義信息,下面的例子中,我們將會創(chuàng)建一個@Configuration類并且加載了外部xml配置。下面展示了一個普通的Java配置類

 
 
 
 
  1. @Configuration 
  2. public class AppConfig { 
  3.  
  4.     @Autowired 
  5.     private DataSource dataSource; 
  6.  
  7.     @Bean 
  8.     public AccountRepository accountRepository() { 
  9.         return new JdbcAccountRepository(dataSource); 
  10.     } 
  11.  
  12.     @Bean 
  13.     public TransferService transferService() { 
  14.         return new TransferService(accountRepository()); 
  15.     } 

下面是system-test-config.xml配置類的一部分

 
 
 
 
  1.  
  2.  
  3.        
  4.      
  5.  
  6.           
  7.        
  8.      
  9.  
  10.      
  11.  
  12.      
  13.            
  14.          
  15.          
  16.          
  17.      
  18.  

引入jdbc.properties建立數(shù)據(jù)庫連接

 
 
 
 
  1. jdbc.driverClassName=com.mysql.jdbc.Driver 
  2. jdbc.url=jdbc:mysql://localhost:3306/sys 
  3. jdbc.username=root 
  4. jdbc.password=123456 
 
 
 
 
  1. public static void main(String[] args) { 
  2.     ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/com/spring/annotation/system-test-config.xml"); 
  3.     TransferService transferService = ctx.getBean(TransferService.class); 
  4.     // ... 

在system-test-config.xml中,AppConfig 對應(yīng)的標簽沒有聲明id屬性,雖然這樣做是可以接受的,但是沒有必要,因為沒有其他bean引用它,并且不太可能通過名稱從容器中獲取它。同樣的,DataSource bean只是按類型自動裝配,因此不嚴格要求顯式的bean id。

使用<> 挑選指定的@Configuration類

因為@Configuration的原注解是@Component,所以@Configuration注解的類也能用于組件掃描,使用與前一個示例中描述的相同的方案,我們可以重新定義system-test-config.xml以利用組件掃描。請注意,在這種情況下,我們不需要顯式聲明,因為啟用相同的功能。

 
 
 
 
  1.  
  2.  
  3.      
  4.      
  5.  
  6.      
  7.            
  8.          
  9.          
  10.          
  11.      
  12.  

@Configuration 類使用@ImportResource

在基于Java注解的配置類中,仍然可以使用少量的@ImportResource導(dǎo)入外部配置,***的方式就是兩者結(jié)合,下面展示了一下Java注解結(jié)合XML配置的示例

 
 
 
 
  1. @Configuration 
  2. @ImportResource("classpath:/com/spring/annotation/properties-config.xml") 
  3. public class AppConfig { 
  4.  
  5.     @Value("${jdbc.driverClassName}") 
  6.       private String driver; 
  7.  
  8.     @Value("${jdbc.url}") 
  9.     private String url; 
  10.  
  11.     @Value("${jdbc.username}") 
  12.     private String username; 
  13.  
  14.     @Value("${jdbc.password}") 
  15.     private String password; 
  16.  
  17.     @Bean 
  18.     public DataSource dataSource() { 
  19.         return new DriverManagerDataSource(url, username, password); 
  20.     } 

Properties-config.xml

 
 
 
 
  1.  
  2.      
  3.  

jdbc.properties

 
 
 
 
  1. jdbc.driverClassName=com.mysql.jdbc.Driver 
  2. jdbc.url=jdbc:mysql://localhost:3306/sys 
  3. jdbc.username=root 
  4. jdbc.password=123456 
 
 
 
 
  1. public static void main(String[] args) { 
  2.     ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); 
  3.     TransferService transferService = ctx.getBean(TransferService.class); 
  4.     // ... 

網(wǎng)頁題目:一文了解和SpringBean有關(guān)的那些注解
文章URL:http://www.dlmjj.cn/article/ccdpgsj.html