zoukankan      html  css  js  c++  java
  • 二、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
    
  • 相关阅读:
    如何用互联网的思维开一家有逼格的客栈?
    create和grant配合使用,对Mysql进行创建用户和对用户授权
    Nginx 403 forbidden原因及故障模拟重现(转载)
    企业级缓存系统varnish应用
    实现基于Haproxy+Keepalived负载均衡高可用架构
    企业级监控zabbix基础
    实现基于Keepalived主从高可用集群网站架构
    实现基于LVS负载均衡集群的电商网站架构
    实现基于lnmp的电子商务网站
    CentOS6编译LAMP基于FPM模式的应用wordpress
  • 原文地址:https://www.cnblogs.com/phtjzzj/p/7582210.html
Copyright © 2011-2022 走看看