SpringBoot3-spring常用配置

一:spring的常用配置

  1,bean的scope
  scope描述了spring容器如何新建bena的实例,spring的scope有以下几种,通过@Scope注解来实现
  1)Singleton:一个spring容器中只有一个bena的实例,此为spring的默认配置,全容器共享一个实例的bean。
  2)Prototype:每次调用新建一个bean的实例
  3)Request:web项目中,给每一个http request新建一个Bean实例
  4)Session :web项目中,给每一个http session新建一个实例
  5)GlobalSession:这个只在portal应用中有用,给每一个global http session新建一个bean实例
   另外,在spring batch中还有一个Scope是使用@StepScope,用在批处理中,

  下面演示默认的single和Prototype,分别从Spring 容器中获得2次Bean,判断Bean的实例是否相等

   下面编写一个singleton的bean,代码如下:

   

package jack.ch2.scope;

import org.springframework.stereotype.Service;

/**
 * Created by jack on 2017/7/9.
 */
//默认为Sinleton,相当于@Scope("singleton")
@Service
public class DemoSingletonService {
}

  下面编写一个prototype的bean:

package jack.ch2.scope;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 * Created by jack on 2017/7/9.
 */
@Service
@Scope("prototype")
public class DemoPrototypeService {
}


  下面是配置类:

package jack.ch2.scope;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * Created by jack on 2017/7/9.
 */
@Configuration
@ComponentScan("jack.ch2.scope")
public class ScopConfig {
}

   下面是测试主类:

package jack.ch2.scope;

import jack.ch1.bean.JavaConfig;
import jack.ch1.bean.UseFunctionService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Created by wj on 2017/7/09.
 */
public class MainTest4 {
    public static void main(String [] args){
        //AnnotationConfigApplicationContext作为spring容器,接受一个配置类作为参数
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopConfig.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();
    }
}


   运行测试程序,测试结果如下:




二:spring EL和资源调用

 spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于jsp的EL表达式语言
 spring开发中经常涉及调用各种资源的情况,包含普通文件,网址,配置文件,系统环境变量等,我们可以使用  spring表达式语言实现资源的注入
 spring主要在注解@Vavle的参数中使用表达式
 下面演示一下几种情况
  1)注入普通字符串
  2)注入操作系统属性
  3)注入表达式运算结果
  4)注入其他Bean的属性
  5)注入文件内容
  6)注入网址内容
  7)注入属性文件


 示例:

 1,准备,增加commons-io可简化文件相关的操作,本例使用commons-io将file转换成字符串:

<!--增加commons-io可简化文件相关操作-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.3</version>
        </dependency>


  在

jack.ch2.el包下新建test.txt,内容随意


  test.txt比如内容如下:

这是test.txt里面的内容,随便写点啥吧

  在jack.ch2.el包下新建test.properties,内容如下:

book.author=jack
book.name=no book name

   注意,我是使用IDEA开发的,上面两个文件其实是放在resources目录下:



   2,需被注入的bean

package jack.ch2.el;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

/**
 * Created by jack on 2017/7/9.
 */
@Service
public class DemoService {
    //注入普通字符串
    @Value("其他类属性")
    private String another;

    public String getAnother() {
        return another;
    }

    public void setAnother(String another) {
        this.another = another;
    }
}


  3,配置类:

package jack.ch2.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;

/**
 * Created by jack on 2017/7/9.
 */
@Configuration
@ComponentScan("jack.ch2.el")
//注入配置文件需要使用@PropertySource指定文件地址,若使用@Value注入,则要配置一个PropertySourcesPlaceholderConfigurer的bean
//注意,@ @Value("${book.name}")使用的是$而不是#
//注入Properties还可以从Environment中获得
@PropertySource("classpath:jack/ch2/el/test.properties")
public class ElConfig {
    //注入普通字符串
    @Value("I Love YOU ROLE!")
    private String normal;
    //注入操作系统属性
    @Value("#{systemProperties['os.name']}")
    private String osName;
    //注入表达式结果
    @Value("#{T(java.lang.Math).random()*100.0}")
    private double randomNumber;
    //注入其他的bean属性
    @Value("#{demoService.another}")
    private String fromAnother;
    //注入文件资源
    @Value("classpath:jack/ch2/el/test.txt")
    private Resource testFile;
    //注入网址资源
    @Value("http://www.baidu.com")
    private Resource testUrl;
    //注入配置文件
    @Value("${book.name}")
    private String bookNmame;

    //注入环境
    @Autowired
    private Environment environment;
    @Bean
    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(bookNmame);
            System.out.println(environment.getProperty("book.author"));

        }catch (Exception e){
            e.printStackTrace();
            System.out.println(e);
        }
    }

}


  测试程序如下:

package jack.ch2.el;

import jack.ch2.scope.DemoPrototypeService;
import jack.ch2.scope.DemoSingletonService;
import jack.ch2.scope.ScopConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Created by jack on 2017/7/09.
 */
public class MainTest5 {
    public static void main(String [] args){
        //AnnotationConfigApplicationContext作为spring容器,接受一个配置类作为参数
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ElConfig.class);
        ElConfig elConfig = context.getBean(ElConfig.class);
        elConfig.outputResource();
        context.close();
    }
}


  测试结果如下:



   pom.xml的配置如下:

   

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jack</groupId>
    <artifactId>springstudy1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--定义属性-->
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!--添加依赖-->
    <dependencies>
        <!--添加spring框架依赖包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>

        <!--spring的aop支持-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <!--aspectj支持-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
        </dependency>

        <!--增加commons-io可简化文件相关操作-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.3</version>
        </dependency>

    </dependencies>

    <!--添加插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


三:Bean的初始化和销毁

    在我们实际开发的时候,经常会遇到在bean使用之前或者之后做一些必要的操作,spring 对bean的生命周期的操作提供了支持。在使用java配置和注解配置下提供如下两种方式:

   1)java配置方式:使用@Bean的initMethod和destroyMethod(相当于xml配置的init-method和destory-method)

   2)注解方式:利用JSR-250的@PostConstruct和@PreDestroy

   1,增加JSR250支持:

 <!--增加JSR250支持-->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
        </dependency>

   2,使用@Bean形式的bean

package jack.ch2.prepost;

/**
 * Created by jack on 2017/7/10.
 * 使用@Bean形式的Bean初始化和销毁方法
 */
public class BeanWayService {
    //构造函数之后执行
    public void init() {
        System.out.println("@Bean-init-method");
    }

    //构造函数
    public BeanWayService() {
        super();
        System.out.println("初始化构造函数-BeanWayService");
    }

    //bean销毁之前执行
    public void destroy() {
        System.out.println("@Bean-destroy-method");
    }
}

   3,使用JSR250形式的bean:

package jack.ch2.prepost;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * Created by jack on 2017/7/10.
 */
public class JSR250WayService {
    //注解方式,注解初始化方法,在构造函数之后执行
    @PostConstruct
    public void init(){
        System.out.println("jsr250-init-method");
    }

    //构造函数
    public JSR250WayService() {
        System.out.println("初始化构造函数-JSR250WayService");
    }

    //注解方法,注解销毁方法,在bean销毁之前执行
    @PreDestroy
    public void destroy(){
        System.out.println("jsr250-destroy-method");
    }
}


    4,配置类

package jack.ch2.prepost;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * Created by jack on 2017/7/10.
 * bean 的初始化和销毁的java配置
 */
@Configuration
//@ComponentScan("com.jack.ch2.prepost")
public class PrePostConfig {
    //initMethod和destroyMethod指定BeanWayService类的init和destroy方法在构造之后,bean销毁之前执行
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public BeanWayService beanWayService(){
        return new BeanWayService();
    }
    @Bean
    public JSR250WayService jsr250WayService(){
        return new JSR250WayService();
    }
}


     5,测试方法如下:

package jack.ch2.prepost;

import jack.ch2.el.ElConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Created by jack on 2017/7/09.
 */
public class MainTest6 {
    public static void main(String [] args){
        //AnnotationConfigApplicationContext作为spring容器,接受一个配置类作为参数
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PrePostConfig.class);
        //initMethod和destroyMethod指定
        BeanWayService beanWayService = context.getBean(BeanWayService.class);
        JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);
        context.close();
    }
}


    运行程序,输入如下:



    可见init方法和destory方法在构造方法之后,bean销毁之前执行。



四:Profile

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

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

    2)通过设定jvm的spring.profiles.active参数来设置配置环境

    3)Web项目设置在Servlet的context parameter中


    下面看一个演示:

  定义一个DemoBean类

package jack.ch2.profile;

/**
 * Created by jack on 2017/7/10.
 */
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;
    }
}


    配置Profile

package jack.ch2.profile;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

/**
 * Created by jack on 2017/7/10.
 */
@Configuration
public class ProfileConfig {
    @Bean
    @Profile("dev")//Profile为dev时实例化devDemoBean
    public DemoBean devDemoBean(){
        return new DemoBean("from development pfofile");
    }
    @Bean
    @Profile("prod")//Profile为prod时实例化prodDemoBean
    public DemoBean prodDemoBean(){
        return new DemoBean("from  production profile");
    }
}


   测试程序如下:

package jack.ch2.profile;

import jack.ch2.prepost.BeanWayService;
import jack.ch2.prepost.JSR250WayService;
import jack.ch2.prepost.PrePostConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Created by jack on 2017/7/09.
 */
public class MainTest7 {
    public static void main(String [] args){
        //AnnotationConfigApplicationContext作为spring容器,接受一个配置类作为参数
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        //先将活动的Profile设置为prod
        context.getEnvironment().setActiveProfiles("prod");
        //后置注册Bean配置类,不然会报bean未定义的错误
        context.register(ProfileConfig.class);
        //刷新容器
        context.refresh();
        DemoBean demoBean = context.getBean(DemoBean.class);
        System.out.println(demoBean.getContent());
        context.close();
    }
}

  运行程序,结果如下:



  将context.getEnvironment().setActiveProfiles("prod");设置为context.getEnvironment().setActiveProfiles("dev");效果如下:




五:事件(Application Event)


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

    spring的事件需要遵循如下流程:

     1)自定义事件,基础ApplicationEvent

     2)定义事件监听器,实现ApplicationListener

     3)使用容器发布事件

     示例如下:

    自定义事件:

package jack.ch2.event;

import org.springframework.context.ApplicationEvent;

/**
 * Created by jack on 2017/7/11.
 * 自定义事件,继承ApplicationEvent
 */
public class DemoEvent extends ApplicationEvent {
    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;
    }
}


事件监听:

package jack.ch2.event;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * Created by jack on 2017/7/11.
 * 事件监听,实现ApplicationListener接口,并指定监听的事件类型
 */
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
    //使用onApplicationEvent方法对消息进行接受处理
    @Override
    public void onApplicationEvent(DemoEvent demoEvent) {
        String msg = demoEvent.getMsg();
        System.out.println("我(bean-demoListener)接收到了bean-demoPublisher发布的消息:"+msg);
    }
}


事件发布类:

package jack.ch2.event;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * Created by jack on 2017/7/11.
 * 事件发布类
 */
@Component
public class DemoPublisher {
    //注入ApplicationContext用来发布事件
    @Autowired
    ApplicationContext applicationContext;
    public void publish(String msg){
        //使用ApplicationContext的publishEvent方法来发布
        applicationContext.publishEvent(new DemoEvent(this,msg));
    }
}


配置类:

package jack.ch2.event;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * Created by jack on 2017/7/11.
 * 配置类
 */
@Configuration
@ComponentScan("jack.ch2.event")
public class EventConfig {
}


 测试代码:

package jack.ch2.event;

import jack.ch2.profile.DemoBean;
import jack.ch2.profile.ProfileConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Created by jack on 2017/7/11.
 */
public class MainTest8 {
    public static void main(String [] args){
        //AnnotationConfigApplicationContext作为spring容器,接受一个配置类作为参数
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
        DemoPublisher demoPublisher = context.getBean(DemoPublisher.class);
        demoPublisher.publish("hello application event");
        context.close();
    }
}


  运行程序,输出如下:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值