Scope描述的是Spring容器是如何新建Bean的实例。 Singleton:一个Spring容器只有一个实例。 Prototype:每次调用都会新建一个Bean的实例。
Singleton和Prototype,分别从Spring容器中获得两次Bean,判断是否相等
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 复制代码
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 复制代码