一、Bean的Scope
Scope描述的是Spring容器如何新建Bean實例的。Spring的Scope有以下幾種,通過@Scope注解來實現。
(1)Singleton:一個Spring容器中只有一個Bean的實例,此為Spring的默認配置,全容器共享一個實例。
(2)Prototype:每次調用新建一個Bean實例。
(3)Request:Web項目中,給每一個 http request 新建一個Bean實例。
(4)Session:Web項目中,給每一個 http session 新建一個Bean實例。
(5)GlobalSession:這個只在portal應用中有用,給每一個 global http session 新建一個Bean實例。
另外,在Spring Batch中還有一個Scope是使用@StepScope,我們將在批處理介紹這個Scope。
接下來簡單演示默認的 Singleton 和 Prototype,分別從Spring容器中獲取兩次Bean,判斷Bean的實例是否相等。
1.編寫Singleton的Bean。
package com.ecworking.scope; import org.springframework.stereotype.Service; @Service //默認為Singleton,相當於@Scope("singleton")。 public class DemoSingletonService { }
2.編寫Prototype的Bean。
package com.ecworking.scope; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @Service @Scope("prototype") //聲明Scopew為Prototype。 public class DemoPrototypeService { }
3.配置類。
package com.ecworking.scope; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.ecworking.scope") public class ScopeConfig { }
4.運行。
package com.ecworking.scope; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class); DemoSingletonService s1 = context.getBean(DemoSingletonService.class); DemoSingletonService s2 = context.getBean(DemoSingletonService.class); DemoPrototypeService p1 = context.getBean(DemoPrototypeService.class); DemoPrototypeService p2 = context.getBean(DemoPrototypeService.class); System.out.println("s1與s2是否相等:" + s1.equals(s2)); System.out.println("p1與p2是否相等:" + p1.equals(p2)); context.close(); } }
運行結果:
二、Spring EL和資源調用
Spring EL-Spring表達式語言,支持在xml和注解中使用表達式,類似於JSP的EL表達式語言。
Spring 開發中經常涉及調用各種資源的情況,包含普通文件、網址、配置文件、系統環境變量等,我們可以使用Spring表達式語言實現資源的注入。
Spring 主要在注解@Value的參數中使用表達式。
本節演示實現以下幾種情況:
(1)注入普通字符;
(2)注入操作系統屬性;
(3)注入表達式運算結果;
(4)注入其他Bean的屬性;
(5)注入文件內容;
(6)注入網址內容;
(7)注入屬性文件;
1. 准備,增加commons-io可簡化文件相關操作。
本例中使用commons-io將file轉換成字符串:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.3</version> </dependency>
在com.ecworking.el.source包下新建test.txt,內容隨意。
在com.ecworking.el.source包下新建test.propertise,內容如下:
book.author = dongyp
book.name = spring boot
2. 需要被注入的Bean。
package com.ecworking.el; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class DemoService { @Value("其他類的屬性") //此處為注入普通字符串 private String another; public String getAnother() { return another; } public void setAnother(String another) { this.another = another; } }
3. 演示類Bean。
package com.ecworking.el; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.env.Environment; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import java.io.IOException; @Service @PropertySource("classpath:test.properties") //注入配置文件需使用@PropertySource指定文件地址,若使用@Value注入,則要配置一個PropertySourcesPlaceholderConfigurer的Bean。注意@Value("${book.name}"),使用的是$而不是#。 //注入 Properties 還可以從 Environment 中獲得。 public class DemoElService { @Value("I LOVE YOU!") //注入普通字符串 private String normal; @Value("#{systemProperties['os.name']}") //注入操作系統屬性 private String osName; @Value("#{T(java.lang.Math).random() * 100.0}") //注入表達式結果 private String randomNumber; @Value("#{demoService.another}") //注入其他Bean屬性 private String fromAnother; @Value("classpath:/test.txt") //注入文件資源 private Resource testFile; @Value("http://www.baidu.com") //注入網址資源 private Resource testUrl; @Value("${book.name}") // 注入配置文件 private String bookName; @Autowired // 注入配置文件 private Environment environment; @Bean // 注入配置文件 public static PropertySourcesPlaceholderConfigurer propertyConfigurer(){ return new PropertySourcesPlaceholderConfigurer(); } public void outputResource(){ try { System.out.println(normal); System.out.println(osName); System.out.println(randomNumber); System.out.println(fromAnother); System.out.println(IOUtils.toString(testFile.getInputStream())); System.out.println(IOUtils.toString(testUrl.getInputStream())); System.out.println(bookName); System.out.println(environment.getProperty("book.author")); } catch (IOException e) { e.printStackTrace(); } } }
4.配置類。
package com.ecworking.el; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.ecworking.el") public class ElConfig { }
5.運行。
package com.ecworking.el; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ElConfig.class); DemoElService demoElService = context.getBean(DemoElService.class); demoElService.outputResource(); context.close(); } }
運行結果: