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
复制代码