zoukankan      html  css  js  c++  java
  • Spring Boot实战(2) Spring常用配置

    1. Bean的Scope

    scope描述Spring容器如何新建Bean的实例。通过注解@Scope实现,取值有:

    a. Singleton:一个Spring容器中只有一个Bean的实例。此为Spring的默认配置,全容器共享一个实例。

    b. Prototype:每次调用新建一个Bean的实例

    c. Request:Web项目中,给每一个Http Request新建一个Bean实例

    d. Session:Web项目中,给每一个Http Session新建一个Bean实例

    e. GlobalSession:这个只在portal应用中有用,给每一个global http session新建一个Bean实例。

    示例:演示Singleton和Prototype分别从Spring容器中获取2次Bean,判断Bean的实例是否相等

    1) 编写Singleton的Bean

      1 package com.ws.study.scope;
      2 
      3 import org.springframework.stereotype.Service;
      4 
      5 // 默认为Singleton,等同于@Scope("singleton")
      6 @Service
      7 public class DemoSingletonService {
      8 }
      9 
    View Code

    2) 编写Prototype的Bean

      1 package com.ws.study.scope;
      2 
      3 import org.springframework.context.annotation.Scope;
      4 import org.springframework.stereotype.Service;
      5 
      6 @Service
      7 // 声明为Prototype
      8 @Scope(value = "prototype")
      9 public class DemoPrototypeService {
     10 }
    View Code

    3) 配置类

      1 package com.ws.study.scope;
      2 
      3 import org.springframework.context.annotation.ComponentScan;
      4 import org.springframework.stereotype.Component;
      5 
      6 @Component
      7 @ComponentScan("com.ws.study.scope")
      8 public class ScopeConfig {
      9 }
     10 
    View Code

    4) 运行类

      1 package com.ws.study.scope;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 
      7 	public static void main(String[] args) {
      8 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);
      9 
     10 		DemoSingletonService s1 = context.getBean(DemoSingletonService.class);
     11 		DemoSingletonService s2 = context.getBean(DemoSingletonService.class);
     12 		System.out.println("s1与s2是否相等:"+s1.equals(s2));
     13 
     14 		DemoPrototypeService p1 = context.getBean(DemoPrototypeService.class);
     15 		DemoPrototypeService p2 = context.getBean(DemoPrototypeService.class);
     16 		System.out.println("p1与p2是否相等:"+p1.equals(p2));
     17 	}
     18 
     19 }
     20 
    View Code

    5) 运行结果

      1 五月 30, 2018 11:13:15 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
      2 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@183da3f: startup date [Wed May 30 23:13:15 CST 2018]; root of context hierarchy
      3 s1与s2是否相等:true
      4 p1与p2是否相等:false
      5 五月 30, 2018 11:13:15 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
      6 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@183da3f: startup date [Wed May 30 23:13:15 CST 2018]; root of context hierarchy
      7 
    View Code

    2. Spring EL和资源调用

    Spring EL为Spring表达式语言,支持在xml和注解中使用表达式。Spring EL实现普通文件、网址、配置文件、系统环境变量等资源的注入。Spring主要在@Value的参数中使用表达式。

    示例:

    1) 加入commons-io依赖

      1 		<dependency>
      2 			<groupId>commons-io</groupId>
      3 			<artifactId>commons-io</artifactId>
      4 			<version>2.3</version>
      5 		</dependency>
    View Code

    2) 包下创建text.txt,内容随意,此示例写入如下:

      1 Spring
    View Code

    3) 包下新建test.properties

      1 test.content=spring
      2 test.date=2018
    View Code

    4) 需被注入的Bean

      1 package com.ws.study.el;
      2 
      3 import org.springframework.beans.factory.annotation.Value;
      4 import org.springframework.stereotype.Service;
      5 
      6 @Service
      7 public class DemoService {
      8 	// 注入普通字符串
      9 	@Value("其他类的属性")
     10 	private String another;
     11 
     12 	public String getAnother() {
     13 		return another;
     14 	}
     15 
     16 	public void setAnother(String another) {
     17 		this.another = another;
     18 	}
     19 }
     20 
    View Code

    5) 配置类

      1 package com.ws.study.el;
      2 
      3 import org.apache.commons.io.IOUtils;
      4 import org.springframework.beans.factory.annotation.Autowired;
      5 import org.springframework.beans.factory.annotation.Value;
      6 import org.springframework.context.annotation.Bean;
      7 import org.springframework.context.annotation.ComponentScan;
      8 import org.springframework.context.annotation.PropertySource;
      9 import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
     10 import org.springframework.core.env.Environment;
     11 import org.springframework.core.io.Resource;
     12 import org.springframework.stereotype.Component;
     13 
     14 @Component
     15 @ComponentScan("com.ws.study.el")
     16 // 注入加载的配置文件
     17 @PropertySource("classpath:com/ws/study/el/test.properties")
     18 public class ElConfig {
     19 
     20 	// 注入普通字符串
     21 	@Value("I love you")
     22 	private String normal;
     23 
     24 	// 注入操作系统属性
     25 	@Value("#{systemProperties['os.name']}")
     26 	private String osName;
     27 
     28 	// 注入表达式结果
     29 	@Value("#{ T(java.lang.Math).random() * 100.0 }")
     30 	private double randomNumber;
     31 
     32 	// 注入其他Bean属性
     33 	@Value("#{demoService.another}")
     34 	private String fromAnother;
     35 
     36 	// 注入文件资源
     37 	@Value("classpath:com/ws/study/el/test.txt")
     38 	private Resource testFile;
     39 
     40 	// 注入Url
     41 	@Value("https://www.baidu.com")
     42 	private Resource testUrl;
     43 
     44 	// 注入配置文件
     45 	// 如果没有上述的@PropertySource,而使用需要@Value加载配置文件,则需配置一个PropertySourcesPlaceholderConfigurer的Bean
     46 	@Value("${test.content}")
     47 	private String content;
     48 
     49 	// 注入配置文件也可以从Environment获取
     50 	@Autowired
     51 	private Environment environment;
     52 
     53 	@Bean
     54 	public static PropertySourcesPlaceholderConfigurer propertyConfigure(){
     55 		return new PropertySourcesPlaceholderConfigurer();
     56 	}
     57 
     58 	public void outputResource(){
     59 		try {
     60 			System.out.println(normal);
     61 			System.out.println(osName);
     62 			System.out.println(randomNumber);
     63 			System.out.println(fromAnother);
     64 			System.out.println(IOUtils.toString(testFile.getInputStream()));
     65 			System.out.println(IOUtils.toString(testUrl.getInputStream()));
     66 			System.out.println(content);
     67 			System.out.println(environment.getProperty("test.content"));
     68 		} catch (Exception e) {
     69 		}
     70 	}
     71 }
     72 
    View Code

    6) 运行类

      1 package com.ws.study.el;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 	public static void main(String[] args) {
      7 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ElConfig.class);
      8 		ElConfig elConfig = context.getBean(ElConfig.class);
      9 		elConfig.outputResource();
     10 		context.close();
     11 	}
     12 }
     13 
    View Code

    7) 运行结果

      1 五月 31, 2018 10:04:31 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
      2 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1bc7afb: startup date [Thu May 31 22:04:31 CST 2018]; root of context hierarchy
      3 I love you
      4 Windows 7
      5 81.51080310192492
      6 其他类的属性
      7 Spring
      8 <!DOCTYPE html>
      9 <!--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><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');
     10                 </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
     11 
     12 spring
     13 spring
     14 五月 31, 2018 10:07:34 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
     15 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1bc7afb: startup date [Thu May 31 22:04:31 CST 2018]; root of context hierarchy
     16 
    View Code

    3. Bean的初始化和销毁

    (1) Spring对Bean的生命周期的操作提供了支持。对于Java配置方式,使用@Bean的initMethod和destroyMethod(相当于xml配置的init-method和destory-method);对于注解方式,使用JSR-250的@PostConstruct和@PreDestroy

    示例:

    1) 增加JSR250支持

      1 		<dependency>
      2 			<groupId>javax.annotation</groupId>
      3 			<artifactId>jsr250-api</artifactId>
      4 			<version>1.0</version>
      5 		</dependency>
    View Code

    2) 使用@Bean形式的Bean

      1 package com.ws.study.prepost;
      2 
      3 public class BeanWayService {
      4 
      5 	public void init(){
      6 		System.out.println("@Bean-init-method");
      7 	}
      8 
      9 	public BeanWayService(){
     10 		super();
     11 		System.out.println("初始化构造函数-BeanWayService");
     12 	}
     13 
     14 	public void destory(){
     15 		System.out.println("@Bean-destroy-method");
     16 	}
     17 }
     18 
    View Code

    3) 使用JSR250形式的Bean

      1 package com.ws.study.prepost;
      2 
      3 import javax.annotation.PostConstruct;
      4 import javax.annotation.PreDestroy;
      5 
      6 public class JSR250WayService {
      7 
      8 	// 在构造函数执行完之后执行
      9 	@PostConstruct
     10 	public void init(){
     11 		System.out.println("jsr250-init-method");
     12 	}
     13 
     14 	public JSR250WayService(){
     15 		super();
     16 		System.out.println("初始化构造函数-JSR250WayService");
     17 	}
     18 
     19 	// 在Bean销毁之前执行
     20 	@PreDestroy
     21 	public void destroy(){
     22 		System.out.println("jsr250-destroy-method");
     23 	}
     24 }
     25 
    View Code

    4) 配置类

      1 package com.ws.study.prepost;
      2 
      3 import org.springframework.context.annotation.Bean;
      4 import org.springframework.context.annotation.ComponentScan;
      5 import org.springframework.context.annotation.Configuration;
      6 
      7 @Configuration
      8 @ComponentScan("com.ws.study.prepost")
      9 public class PrePostConfig {
     10 
     11 	// initMethod和destroyMethod指定BeanWayService类的init和destroy方法在构造之后、Bean销毁之前执行
     12 	@Bean(initMethod = "init", destroyMethod = "destory")
     13 	BeanWayService beanWayService(){
     14 		return new BeanWayService();
     15 	}
     16 
     17 	@Bean
     18 	JSR250WayService jsr250WayService(){
     19 		return new JSR250WayService();
     20 	}
     21 }
     22 
    View Code

    5) 运行类

      1 package com.ws.study.prepost;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 
      7 	public static void main(String[] args) {
      8 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PrePostConfig.class);
      9 
     10 		BeanWayService beanWayService = context.getBean(BeanWayService.class);
     11 		JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);
     12 
     13 		context.close();
     14 	}
     15 
     16 }
     17 
    View Code

    6) 运行结果

      1 五月 31, 2018 10:33:21 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
      2 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@dbe50f: startup date [Thu May 31 22:33:21 CST 2018]; root of context hierarchy
      3 初始化构造函数-BeanWayService
      4 @Bean-init-method
      5 初始化构造函数-JSR250WayService
      6 jsr250-init-method
      7 五月 31, 2018 10:35:58 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
      8 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@dbe50f: startup date [Thu May 31 22:33:21 CST 2018]; root of context hierarchy
      9 jsr250-destroy-method
     10 @Bean-destroy-method
     11 
    View Code

    4. Profile

    Profile为在不同环境下使用不同的配置提供了支持(开发环境下的配置和生产环境下的配置肯定是不同的,如数据库配置)。

    a. 通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。开发中使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean

    b. 通过设定jvm的srping.profiles.active参数来设置配置环境

    c. Web项目设置在Servlet的context parameter中

    示例:

    1) 示例Bean

      1 package com.ws.study.profile;
      2 
      3 public class DemoBean {
      4 
      5 	private String content;
      6 
      7 
      8 	public DemoBean(String content){
      9 		super();
     10 		this.content = content;
     11 	}
     12 
     13 	public String getContent() {
     14 		return content;
     15 	}
     16 
     17 	public void setContent(String content) {
     18 		this.content = content;
     19 	}
     20 
     21 }
     22 
    View Code

    2) Profile配置

      1 package com.ws.study.profile;
      2 
      3 import org.springframework.context.annotation.Bean;
      4 import org.springframework.context.annotation.Configuration;
      5 import org.springframework.context.annotation.Profile;
      6 
      7 @Configuration
      8 public class ProfileConfig {
      9 
     10 	@Bean
     11 	// Profile为dev时实例化devDemoBean
     12 	@Profile("dev")
     13 	public DemoBean devDemoBean(){
     14 		return new DemoBean("from devlopment profile");
     15 	}
     16 
     17 	@Bean
     18 	// Profile为prod时实例化prodDemoBean
     19 	@Profile("prod")
     20 	public DemoBean proDemoBean(){
     21 		return new DemoBean("from production profile");
     22 	}
     23 }
    View Code

    3) 运行类

      1 package com.ws.study.profile;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 
      7 	public static void main(String[] args) {
      8 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
      9 		// 先将活动的Profile设置为prod
     10 		context.getEnvironment().setActiveProfiles("prod");
     11 		// 后置注册Bean配置类,不然会报Bean未定义的错误
     12 		context.register(ProfileConfig.class);
     13 		// 刷新容器
     14 		context.refresh();
     15 
     16 		DemoBean demoBean = context.getBean(DemoBean.class);
     17 
     18 		System.out.println(demoBean.getContent());
     19 
     20 		context.close();
     21 	}
     22 
     23 }
     24 
    View Code

    4) 设置为prod的运行结果

      1 五月 31, 2018 11:04:32 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
      2 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@dbe50f: startup date [Thu May 31 23:04:31 CST 2018]; root of context hierarchy
      3 from production profile
      4 五月 31, 2018 11:05:05 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
      5 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@dbe50f: startup date [Thu May 31 23:04:31 CST 2018]; root of context hierarchy
      6 
    View Code

    5) 设置为dev的运行结果

      1 五月 31, 2018 11:06:21 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
      2 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1a71e93: startup date [Thu May 31 23:06:21 CST 2018]; root of context hierarchy
      3 from devlopment profile
      4 五月 31, 2018 11:06:22 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
      5 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1a71e93: startup date [Thu May 31 23:06:21 CST 2018]; root of context hierarchy
      6 
    View Code

    5. 事件(Application Event)

    Spring的事件为Bean和Bean之间的消息通信提供了支持。当一个Bean处理完一个任务之后,希望另一个Bean知道并能做相应的处理。这时我们就需要让另外一个Bean监听当前Bean所发送的事件。

    Spring事件需要遵循的流程:

    a. 自定义事件,继承ApplicationEvent

    b. 定义事件监听器,实现ApplicationListener

    c. 使用容器发布事件

    示例:

    1) 自定义事件

      1 package com.ws.study.event;
      2 
      3 import org.springframework.context.ApplicationEvent;
      4 
      5 public class DemoEvent extends ApplicationEvent{
      6 	private static final long serialVersionUID = -7872648566400668161L;
      7 
      8 	private String msg;
      9 
     10 	public DemoEvent(Object source, String msg) {
     11 		super(source);
     12 		this.msg = msg;
     13 	}
     14 
     15 	public String getMsg() {
     16 		return msg;
     17 	}
     18 
     19 	public void setMsg(String msg) {
     20 		this.msg = msg;
     21 	}
     22 }
     23 
    View Code

    2) 事件监听器

      1 package com.ws.study.event;
      2 
      3 import org.springframework.context.ApplicationListener;
      4 import org.springframework.stereotype.Component;
      5 
      6 @Component
      7 // 实现ApplicationListener接口,并指定监听的时间类型
      8 public class DemoListener implements ApplicationListener<DemoEvent>{
      9 
     10 	// 使用onApplicationEvent方法对消息进行接受处理
     11 	public void onApplicationEvent(DemoEvent event) {
     12 		String msg = event.getMsg();
     13 		System.out.println("我(bean-demoListener)接受到了bean-demoEvent发布的消息: "+msg);
     14 	}
     15 }
     16 
    View Code

    3) 事件发布类

      1 package com.ws.study.event;
      2 
      3 import org.springframework.beans.factory.annotation.Autowired;
      4 import org.springframework.context.ApplicationContext;
      5 import org.springframework.stereotype.Component;
      6 
      7 @Component
      8 public class DemoPublisher {
      9 
     10 	// 注入ApplicationContext用来发布事件
     11 	@Autowired
     12 	ApplicationContext applicationContext;
     13 
     14 	public void publish(String msg){
     15 		// 使用ApplicationContext的publishEvent方法来发布
     16 		applicationContext.publishEvent(new DemoEvent(this, msg));
     17 	}
     18 }
     19 
    View Code

    4) 配置类

      1 package com.ws.study.event;
      2 
      3 import org.springframework.context.annotation.ComponentScan;
      4 import org.springframework.stereotype.Component;
      5 
      6 @Component
      7 @ComponentScan("com.ws.study.event")
      8 public class EventConfig {
      9 }
     10 
    View Code

    5) 运行类

      1 package com.ws.study.event;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 	public static void main(String[] args) {
      7 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
      8 		DemoPublisher demoPublisher = context.getBean(DemoPublisher.class);
      9 		demoPublisher.publish("hello application envent");
     10 		context.close();
     11 	}
     12 }
     13 
    View Code

    6) 运行结果

      1 五月 31, 2018 11:23:18 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
      2 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@dbe50f: startup date [Thu May 31 23:23:18 CST 2018]; root of context hierarchy
      3 我(bean-demoListener)接受到了bean-demoEvent发布的消息: hello application envent
      4 五月 31, 2018 11:25:15 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
      5 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@dbe50f: startup date [Thu May 31 23:23:18 CST 2018]; root of context hierarchy
      6 
    View Code
  • 相关阅读:
    Rotate List
    Spiral Matrix II
    Jump Game
    Maximum Subarray
    Pow(x, n)
    Anagrams
    Permutations
    unity 相机的问题
    NGUI 学习
    空间数据库1
  • 原文地址:https://www.cnblogs.com/mengrennwpu/p/9114385.html
Copyright © 2011-2022 走看看