Spring學習地址:how2j.cn/k/spring/sp…css
Scope描述的是Spring容器是如何新建Bean的實例。html
Singleton:一個Spring容器只有一個實例。java
Prototype:每次調用都會新建一個Bean的實例。spring
Singleton和Prototype,分別從Spring容器中得到兩次Bean,判斷是否相等apache
package com.eleven.scope1;
import org.springframework.stereotype.Service;
@Service // 表示當前類是Spring管理的一個Bean
// @Scope("singleton") 默認爲Singleton,因此註釋掉
public class DemoSingletonService {
}
複製代碼
package com.eleven.scope1;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service // 表示當前類是Spring管理的一個Bean
@Scope("prototype") // 聲明scope爲prototype
public class DemoPrototypeService {
}
複製代碼
package com.eleven.scope1;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 聲明當前類是一個配置類
@ComponentScan("com.eleven.scope1") // 自動掃描包下面的全部配置
public class ScopeConfig {
}
複製代碼
package com.eleven.scope1;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// 聲明AnnotationConfigApplicationContext是Spring管理的一個Bean,將ScopeConfig注入進去
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);
// 獲取DemoSingletonService聲明的Bean
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("Singleton:s1和s2是否相等:" + s1.equals(s2));
System.out.println("Prototype:p1和p2是否相等:" + p1.equals(p2));
context.close();
}
}
複製代碼
Singleton:s1和s2是否相等:true
Prototype:p1和p2是否相等:false
複製代碼
支持在xml和註解裏面使用表達式,能夠利用Spring的表達式語言實現資源注入。api
使用Spring注入如下內容:(1)字符串(2)操做系統屬性(3)表達式運算結果(4)其它Bean屬性(5)文件內容(6)網址內容(7)屬性文件app
<!-- 將file轉化成字符串 -->
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
複製代碼
wqewrhigndfvalmf
文件高級工我按揭我給你
!@#¥%……&*()——
複製代碼
study.author=eleven
study.name=spring boot
複製代碼
package com.eleven.el;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service // 使用註解聲明表示DemoService類是Spring管理的一個Bean
public class DemoService {
@Value("其它類的屬性") // 此處爲注入普通字符串
private String another;
/** get和set */
public String getAnother() {
return another;
}
public void setAnother(String another) {
this.another = another;
}
}
複製代碼
package com.eleven.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.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("com.eleven.el") // 自動掃描包下面的全部註解
@PropertySource("classpath:com/eleven/el/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:com/eleven/el/test.txt") // 注入文件資源
private Resource testFile;
@Value("https://www.baidu.com") // 注入網址資源
private Resource testUrl;
@Value("${study.name}") // 注入配置文件
private String studyName;
@Autowired // 將Environment注入到ElConfig裏面
private Environment environment; // 注入配置文件
@Bean // 表示當前方法的返回值是一個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(studyName);
System.out.println(environment.getProperty("study.author"));
} catch(Exception e) {
e.printStackTrace();
}
}
}
複製代碼
package com.eleven.el;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ElConfig.class);
ElConfig resourceSevice = context.getBean(ElConfig.class);
resourceSevice.outputResource();
context.close();
}
}
複製代碼
I Love You!
Windows 10
94.68825963827781
其它類的屬性
wqewrhigndfvalmf
文件高級工我按揭我給你
!@#¥%……&*()——
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css>......
spring boot
eleven
複製代碼
Spring對Bean的生命週期提供了支持,共有2種方式。dom
用Java配置的方式和註解的方式來描述Bean的初始化和銷燬。ide
<!-- Java規範提案 -->
<!-- https://mvnrepository.com/artifact/javax.annotation/jsr250-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
複製代碼
package com.eleven.beaninitdestory1;
public class BeanWayService {
public void init() {
System.out.println("Bean初始化該方法");
}
public BeanWayService() {
super();
System.out.println("初始化構造函數");
}
public void destroy() {
System.out.println("Bean銷燬該方法");
}
}
複製代碼
package com.eleven.beaninitdestory1;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class JSR250WayService {
@PostConstruct
public void init() {
System.out.println("jsr250初始化該方法");
}
public JSR250WayService() {
super();
System.out.println("初始化構造函數");
}
@PreDestroy
public void destroy() {
System.out.println("jsr250銷燬該方法");
}
}
複製代碼
package com.eleven.beaninitdestory1;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 聲明當前類是一個配置類
@ComponentScan("com.eleven.beaninitdestory1") // 自動掃描包下面的全部配置
public class PrePostConfig {
@Bean(initMethod = "init", destroyMethod = "destroy") // 初始化的方法和銷燬的方法都是對應BeanWayService裏面的方法
BeanWayService beanWayService() {
return new BeanWayService();
}
@Bean
JSR250WayService jsr250WayService() {
return new JSR250WayService();
}
}
複製代碼
package com.eleven.beaninitdestory1;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PrePostConfig.class);
// Java配置
BeanWayService beanWayService = context.getBean(BeanWayService.class);
// 註解配置
JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);
context.close();
}
}
複製代碼
初始化構造函數
jsr250初始化該方法
初始化構造函數
Bean初始化該方法
十二月 04, 2019 5:17:39 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5e9f23b4: startup date [Wed Dec 04 17:17:39 CST 2019]; root of context hierarchy
Bean銷燬該方法
jsr250銷燬該方法
複製代碼
Profile表示能夠在不一樣環境下使用不一樣的配置。函數
經過使用Profile註解,來配置生產/開發環境。
package com.eleven.profile;
public class DemoBean {
private String content;
public DemoBean(String context) {
super();
this.content = context;
}
/** get/set方法 */
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
複製代碼
package com.eleven.profile;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration // 聲明當前類是一個配置類
public class ProfileConfig {
@Bean // 表示當前類的返回值就是一個Bean
@Profile("dev")
public DemoBean devDemoBean() {
return new DemoBean("開發環境");
}
@Bean
@Profile("prod")
public DemoBean prodDemoBean() {
return new DemoBean("生產環境");
}
}
複製代碼
package com.eleven.profile;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// 使用AnnotationConfigApplicationContext做爲Spring的容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 經過設定Environment的ActiveProfiles來設定當前context的配置環境
context.getEnvironment().setActiveProfiles("prod"); // 先將活動的Profile設置爲Prod
// context.getEnvironment().setActiveProfiles("dev"); // 表示開發環境
context.register(ProfileConfig.class); // 註冊Bean的配置類
context.refresh(); // 刷新容器
// 得到DemoBean聲明的Bean
DemoBean demoBean = context.getBean(DemoBean.class);
System.out.println(demoBean.getContent());
context.close();
}
}
複製代碼
生產環境
複製代碼
Spring的事件爲Bean和Bean之間的消息通訊提供了支持。
當一個Bean處理完一個任務以後,但願可以被其它Bean知道並做出相應的處理,這時,咱們就須要讓其它Bean監聽當前Bean所發送的事件。
1.自定義事件,集成ApplicationEvent。
2.定義事件監聽器,實現ApplicationListener。
3.使用容器發佈事件。
package com.eleven.event;
import org.springframework.context.ApplicationEvent;
public class DemoEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
private String msg;
/** get/set **/
public DemoEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
複製代碼
package com.eleven.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component // 將普通的pojo對象實例化到Spring容器中
public class DemoListener implements ApplicationListener<DemoEvent> { // 實現了ApplicationListener接口,並指定監聽事件的類型
@Override
public void onApplicationEvent(DemoEvent event) { // 使用onApplicationEvent方法對消息進行接收處理
String msg = event.getMsg();
System.out.println("我(bean-demoListener)接收到了bean-demoPublisher發佈的消息:" + msg);
}
}
複製代碼
package com.eleven.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 applicationContext; // 注入ApplicationContext用來發布事件
public void publish(String msg) {
applicationContext.publishEvent(new DemoEvent(this, msg)); // 使用ApplicationContext的PublishEvent方法來發布
}
}
複製代碼
package com.eleven.event;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 聲明當前是一個配置類
@ComponentScan("com.eleven.event") // 自動掃描包下面因此的配置
public class EventConfig {
}
複製代碼
package com.eleven.event;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// 將AnnotationConfigApplicationContext做爲Spring的容器,並將參數配置進去
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
// 得到DemoPublisher的聲明Bean
DemoPublisher demoPublisher = context.getBean(DemoPublisher.class);
// 發佈消息
demoPublisher.publish("Hello Application Event");
context.close();
}
}
複製代碼
我(bean-demoListener)接收到了bean-demoPublisher發佈的消息:Hello Application Event
複製代碼