二、spring常用配置

2.1 Bean的Scope

2.1.1简介

Scope描述的是Spring容器如何新建Bean的实例的。Spring的Scope有以下几种,通过@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实例。


示例
(1)编写Singleton的Bean

package com.wisely.highlight_spring4.ch2.scope; 

@Service //1 
public class DemoSingletonService { 
} 

①默认为Singleton,相当于@Scope(“singleton”)。

(2)编写Prototype的Bean

package com.wisely.highlight_spring4.ch2.scope; 

@Service 
@Scope("prototype")//1 
public class DemoPrototypeService { 
} 

①声明Scope为Prototype。

(3)配置类

package com.wisely.highlight_spring4.ch2.scope; 

@Configuration 
@ComponentScan("com.wisely.highlight_spring4.ch2.scope") 
public class ScopeConfig { 
} 

(4)运行

package com.wisely.highlight_spring4.ch2.scope;

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); 
  
        DemoPrototypeService p1 = context.getBean(DemoPrototypeService.class); 
        DemoPrototypeService p2 = context.getBean(DemoPrototypeService.class); 
  
        System.out.println("s1与s2是否相等:"+s1.equals(s2)); 
        System.out.println("p1与p2是否相等:"+p1.equals(p2)); 
        
        context.close(); 
    } 
} 

(5)结果

s1与s2是否相等:true
p1与p2是否相等:false

2.2 Spring EL和资源调用

Spring EL:Spring表达式语言,支持在xml和注解中使用表达式
Spring开发中经常涉及调用各种资源的情况,包含普通文件、网址、配置文件、系统环境变量等,我们可以使用Spring的表达式语言实现资源的注入
Spring主要在注解@Value的参数中使用表达式。


示例
(1)准备,增加commons-io可简化文件相关操作

<dependency> 
    <groupId>commons-io</groupId> 
    <artifactId>commons-io</artifactId> 
    <version>2.3</version> 
</dependency>

在com.wisely.highlight_spring4.ch2.el包下新建test.txt,内容随意。
在com.wisely.highlight_spring4.ch2.el包下新建test.properties,内容如下:

book.author=wangyunfei 
book.name=spring boot

(2)需被注入的Bean

package com.wisely.highlight_spring4.ch2.el; 

@Service 
public class DemoService { 
    @Value("其他类的属性") //1 
    private String another; 
  
    public String getAnother() { 
        return another; 
    } 
    public void setAnother(String another) { 
        this.another = another; 
    } 
} 

①此处为注入普通字符串

(3)演示配置类

package com.wisely.highlight_spring4.ch2.el; 

@Configuration 
@ComponentScan("com.wisely.highlight_spring4.ch2.el") 
@PropertySource("classpath:com/wisely/highlight_spring4/ch2/el/test.properties")//7 
public class ElConfig { 
    
    @Value("I Love You!") //1 
    private String normal; 
  
    @Value("#{systemProperties['os.name']}") //2 
    private String osName; 
    
    @Value("#{ T(java.lang.Math).random() * 100.0 }") //3 
    private double randomNumber; 
  
    @Value("#{demoService.another}") //4 
    private String fromAnother; 
  
    @Value("classpath:com/wisely/highlight_spring4/ch2/el/test.txt") //5 
    private Resource testFile; 
  
    @Value("http://www.baidu.com") //6 
    private Resource testUrl; 
    
    @Value("${book.name}") //7 
    private String bookName; 
  
    @Autowired 
    private Environment environment; //7 
    
    @Bean //7 
    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属性。
⑤注入文件资源。
⑥注入网址资源。
⑦注入配置文件。
注入配置配件需使用@PropertySource指定文件地址,若使用@Value注入,则要配置一个PropertySourcesPlaceholderConfigurer的Bean。注意,@Value("({book.name}")使用的是“)”,而不是“#”。
注入Properties还可从Environment中获得。

(4)运行

package com.wisely.highlight_spring4.ch2.el; 

public class Main { 
    
    public static void main(String[] args) { 
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ResourceConfig.class); 
          
         ElConfig resourceService = context.getBean(ElConfig.class); 
         resourceService.outputResource(); 
         context.close(); 
    } 
} 

(5)结果

I Love You!
Windows 10.0
32.2342342345435345234234
其他类的属性
测试文件
<!D..................

2.3 Bean的初始化和销毁

经常会遇到在Bean在使用之前或者之后做些必要的操作,Spring对Bean的生命周期的操作提供了支持。
在使用Java配置和注解配置下提供如下两种方式:
(1)Java配置方式:使用@Bean的initMethod和destroyMethod(相当于xml配置的init-method和destory-method)。
(2)注解方式:利用JSR-250的@PostConstruct和@PreDestroy。


示例
(1)增加JSR250支持

<dependency> 
    <groupId>javax.annotation</groupId> 
    <artifactId>jsr250-api</artifactId> 
    <version>1.0</version> 
</dependency> 

(2)使用@Bean形式的Bean

package com.wisely.highlight_spring4.ch2.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"); 
    } 
} 

(3)使用JSR250形式的Bean

package com.wisely.highlight_spring4.ch2.prepost; 

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"); 
    } 
} 

①@PostConstruct,在构造函数执行完之后执行。
②@PreDestroy,在Bean销毁之前执行。

(4)配置类

package com.wisely.highlight_spring4.ch2.prepost; 

@Configuration 
@ComponentScan("com.wisely.highlight_spring4.ch2.prepost") 
public class PrePostConfig { 
    
    @Bean(initMethod="init",destroyMethod="destroy") //1 
    BeanWayService beanWayService(){ 
        return new BeanWayService(); 
    } 
    @Bean 
    JSR250WayService jsr250WayService(){ 
        return new JSR250WayService(); 
    } 
} 

①initMethod和destroyMethod指定BeanWayService类的init和destroy方法在构造之后、Bean销毁之前执行。

(5)运行

package com.wisely.highlight_spring4.ch2.prepost; 

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(); 
    } 
} 

(6)结果

初始化构造函数-BeanWayService   
@Bean-init-method
初始化构造函数-JSR250WayService
jsr250-init-method
jsr250-destory-method
@Bean-destory-method

2.4 Profile

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

(1)通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。在开发中使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。
(2)通过设定jvm的spring.profiles.active参数来设置配置环境。
(3)Web项目设置在Servlet的context parameter中。


示例
(1)示例Bean

package com.wisely.highlight_spring4.ch2.profile; 

public class DemoBean { 
    private String content; 
    public DemoBean(String content) { 
        super(); 
        this.content = content; 
         } 
    public String getContent() { 
        return content; 
    } 
    public void setContent(String content) { 
        this.content = content; 
    } 
} 

(2)Profile配置

package com.wisely.highlight_spring4.ch2.profile; 

@Configuration 
public class ProfileConfig { 
    @Bean 
    @Profile("dev") //1 
    public DemoBean devDemoBean() { 
        return new DemoBean("from development profile"); 
    } 
  
    @Bean 
    @Profile("prod") //2 
    public DemoBean prodDemoBean() { 
        return new DemoBean("from production profile"); 
    } 
} 

①Profile为dev时实例化devDemoBean。
②Profile为prod时实例化prodDemoBean。

(3)运行

package com.wisely.highlight_spring4.ch2.profile; 

public class Main { 
  
    public static void main(String[] args) { 
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 
          
        context.getEnvironment().setActiveProfiles("prod"); //1 
        context.register(ProfileConfig.class);//2 
        context.refresh(); //3 
        DemoBean demoBean = context.getBean(DemoBean.class); 
        
        System.out.println(demoBean.getContent()); 
        context.close(); 
    } 
} 

①先将活动的Profile设置为prod。
②后置注册Bean配置类,不然会报Bean未定义的错误。
③刷新容器。

(4)结果

from production profile

2.5事件(Application Event)

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

Spring的事件需要遵循如下流程:
(1)自定义事件,集成ApplicationEvent。
(2)定义事件监听器,实现ApplicationListener。
(3)使用容器发布事件。


示例
(1)自定义事件

package com.wisely.highlight_spring4.ch2.event;

public class DemoEvent extends ApplicationEvent{ 
    private static final long serialVersionUID = 1L; 
    private String msg; 
  
    public DemoEvent(Object source,String msg) { 
        super(source); 
        this.msg = msg; 
    } 
    public String getMsg() { 
        return msg; 
    } 
    public void setMsg(String msg) { 
        this.msg = msg; 
    } 
} 

(2)事件监听器

package com.wisely.highlight_spring4.ch2.event; 

@Component 
public class DemoListener implements ApplicationListener<DemoEvent> {//1 
  
    public void onApplicationEvent(DemoEvent event) {//2 
        String msg = event.getMsg(); 
        System.out.println("我(bean-demoListener)接收到了bean-demoPublisher发布的消息:"+ msg); 
    } 
} 

①实现ApplicationListener接口,并指定监听的事件类型。
②使用onApplicationEvent方法对消息进行接受处理。

(3)事件发布类

package com.wisely.highlight_spring4.ch2.event; 

@Component 
public class DemoPublisher { 
    @Autowired 
    ApplicationContext applicationContext; //1 
    
    public void publish(String msg){ 
        applicationContext.publishEvent(new DemoEvent(this, msg)); //2 
    }
} 

①注入ApplicationContext用来发布事件。
②使用ApplicationContext的publishEvent方法来发布。

(4)配置类

package com.wisely.highlight_spring4.ch2.event; 
  
@Configuration 
@ComponentScan("com.wisely.highlight_spring4.ch2.event") 
public class EventConfig { 
} 

(5)运行

public class Main { 
  
    public static void main(String[] args) { 
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class); 
          
         DemoPublisher demoPublisher = context.getBean(DemoPublisher.class); 
         demoPublisher.publish("hello application event"); 
         context.close(); 
    } 
} 

(6)结果

我(bean-demoListener)接收到了bean-demoPublisher发布的消息:hello application event
原文地址:https://www.cnblogs.com/phtjzzj/p/7582210.html