一、Bean的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實例
示例如下
//Prototype的bean類
package service.scope;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
//Prototype:每次調用新建一個Bean實例
@Scope("prototype")
public class DemoPrototypeService {}
//Singleton類
package service.scope;
import org.springframework.stereotype.Service;
@Service
//默認@Scope("Singleton"),Singleton:一個Spring容器只有一個Bean實例,此爲Spring默認配置,全容器共享一個實例
public class DemoSingletonService {}
//配置類
package service.scope;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.scope")
public class ScopeConfig {}
//測試類
package service.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);
System.out.println("s1與s2是否相等:"+(s1==s2));//true
DemoPrototypeService p1=context.getBean(DemoPrototypeService.class);
DemoPrototypeService p2=context.getBean(DemoPrototypeService.class);
System.out.println("p1與p2是否相等:"+(p1==p2));//false
}
}
二、Spring EL 與資源調用
spring EL 也就是Spring表達式語言,支持在xml和註解中使用表達式,類似於JSP的EL表達式語言。
Spring開發中我們可能經常涉及到調用各種資源的情況,包含普通文件、網址、配置文件、系統環境變量等,我們可以使用Spring的表達式語言實現資源的注入。
Spring主要在註解@Value的參數中使用表達式。如:
1、注入普通的字符串
2、注入操作系統屬性
3、注入表達式運算結果
4、注入其他Bean的屬性
5、注入文件內容
6、注入網址內容
7、注入屬性文件
示例如下:
//需被注入的bean
package service.elspring;
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;
}
}
//演示配置類
package service.elspring;
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.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
/*
* 演示配置類
*/
@Configuration
@ComponentScan("service.elspring")
@PropertySource("classpath:service/elspring/test.properties")
public class ElConfig {
@Value("I Love You!") //注入普通字符串
private String normal;
@Value("#{systemProperties['os.name']}") //注入操作系統屬性
private String osName;
@Value("#{ T(java.lang.Math).random() * 100.0 }") //注入表達式結果
private double randomNumber;
@Value("#{demoService.another}") //注入其他bean屬性
private String fromAnother;
@Value("classpath:service/elspring/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 propertyConfigure() {
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 (Exception e) {
e.printStackTrace();
}
}
}
三、Bean的初始化和銷燬
實際開發中經常遇到在Bean在使用之前或者之後做些必要的操作,Spring對Bean的生命週期的操作提供了支持,在使用java配置和註解配置下提供如下兩種方式:
1、Java配置方式:使用@Bean的initMethod和destoryMethod(相當於xml配置的init-method和destory-method)
2、註解方式:利用JSR-250的@PostConstruct和@PreDestroy
示例如下:
package service.prepost;
public class BeanWayService {
public void init(){
System.out.println("@Bean-init-method");
}
public BeanWayService() {
super();
System.out.println("初始化構造函數-BeanWayService");
}
public void destroy(){
System.out.println("@Bean-destory-method");
}
}
package service.prepost;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class JSR250WayService {
@PostConstruct //1
public void init(){
System.out.println("jsr250-init-method");
}
public JSR250WayService() {
super();
System.out.println("初始化構造函數-JSR250WayService");
}
@PreDestroy //2
public void destroy(){
System.out.println("jsr250-destory-method");
}
}
package service.prepost;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.prepost")
public class PrePostConfig {
@Bean(initMethod="init",destroyMethod="destroy") //1
BeanWayService beanWayService(){
return new BeanWayService();
}
@Bean
JSR250WayService jsr250WayService(){
return new JSR250WayService();
}
}
package service.prepost;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(PrePostConfig.class);
BeanWayService beanWayService = context.getBean(BeanWayService.class);
JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);
context.close();
}
}
四、事件
Spring的事件爲Bean與Bean之間的消息通信提供了支持。當一個Bean處理完一個任務之後,希望另一個Bean知道並能做相應的處理,這時我們呢就需要讓另一個Bean監聽當前Bean所發送的事件。
Spring的事件需要遵循如下流程:
1、自定義事件,集成ApplicationEvent.
2、定義事件監聽器,實現ApplicationListener
3、使用容器發佈事件
示例:
//自定義事件
package service.event;
import org.springframework.context.ApplicationEvent;
/*
* 自定義事件
*/
public class DemoEvent extends ApplicationEvent{
private static final long serialVersionUID = 1L;
private String msg;
public DemoEvent(Object source,String msg) {
super(source);
// TODO Auto-generated constructor stub
this.msg=msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
//事件監聽器
package service.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/*
* 事件監聽類
*/
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
@Override
public void onApplicationEvent(DemoEvent event) {
// TODO Auto-generated method stub
String msg=event.getMsg();
System.out.println("我bean-demoListener接收到了"+"bean-demopublic的信息"+msg);
}
}
//事件發佈類
package service.event;
/*
* 事件發佈類
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;
public void publisher(String msg){
applicationContext.publishEvent(new DemoEvent(this,msg));
}
}
//配置類
package service.event;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.event")
public class EventConfig {}
//測試類
package service.event;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(EventConfig.class);
DemoPublisher demoPublisher=context.getBean(DemoPublisher.class);
demoPublisher.publisher("hello appliaction event");
context.close();
}
}
maven的pom.xml配置文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!--聲明項目描述符遵循哪一個POM模型版本。這是爲了當Maven引入了新的特性或者其他模型變更的時候,確保穩定性。-->
<modelVersion>4.0.0</modelVersion>
<!--父項目的座標。如果項目中沒有規定某個元素的值,那麼父項目中的對應值即爲項目的默認值。 座標包括group ID,artifact ID和 version。-->
<parent>
<!--被繼承的父項目的構件標識符-->
<groupId>org.springframework.boot</groupId>
<!--被繼承的父項目的全球唯一標識符-->
<artifactId>spring-boot-starter-parent</artifactId>
<!--被繼承的父項目的版本-->
<version>1.3.5.RELEASE</version>
<!--父項目的pom.xml文件的相對路徑。相對路徑允許你選擇一個不同的路徑。默認值是../pom.xml。Maven首先在構建當前項目的地方尋找父項目的pom,其次在文件系統的這個位置(relativePath位置),然後在本地倉庫,最後在遠程倉庫尋找父項目的pom。-->
<relativePath></relativePath>
</parent>
<!--項目的唯一標識符,通常使用全限定的包名區分該項目和其他項目。並且構建時生成的路徑也是由此生成, 如com.mycompany.app生成的相對路徑爲:/com/bocom-->
<groupId>com.bocom</groupId>
<!--構件的標識符,它和group ID一起唯一標識一個構件。換句話說,
你不能有兩個不同的項目擁有同樣的artifact ID和groupID;在某個特定的group ID下,artifact ID也必須是唯一的。
構件是項目產生的或使用的一個東西,Maven爲項目產生的構件包括:JARs,源碼,二進制發佈和WARs等。-->
<artifactId>testmaven</artifactId>
<!--項目產生的構件類型,例如jar、war、ear、pom。插件可以創建他們自己的構件類型,所以前面列的不是全部構件類型-->
<packaging>war</packaging>
<!--項目當前版本,格式爲:主版本.次版本.增量版本-限定版本號-->
<version>0.0.1-SNAPSHOT</version>
<!--項目的名稱, Maven產生的文檔用-->
<name>testmaven Maven Webapp</name>
<!--項目主頁的URL, Maven產生的文檔用-->
<url>http://maven.apache.org</url>
<!--項目的詳細描述, Maven 產生的文檔用。 當這個元素能夠用HTML格式描述時(例如,CDATA中的文本會被解析器忽略,就可以包含HTML標籤), 不鼓勵使用純文本描述。如果你需要修改產生的web站點的索引頁面,你應該修改你自己的索引頁文件,而不是調整這裏的文檔。-->
<description>A maven project to study maven and boot</description>
<!--該元素描述了項目相關的所有依賴。 這些依賴組成了項目構建過程中的一個個環節。它們自動從項目定義的倉庫中下載。-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加spring aop支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- aspectj支持 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
</dependencies>
<build>
<finalName>testmaven</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin </artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>