二-Spring常用配置(1)-Scope、EL-【JavaEE开发的颠覆者】

127 阅读3分钟

一、Bean的Scope

Scope描述的的Spring容器如何新建Bean的实例的。
1.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实例。

2.示例–演示singleton和Prototype
分别从Spring容器中获得两次Bean,判断Bean的实例是否相同。
(1)Singleton的Bean

//Singleton的Bean
@Service
public class ScopeSingletonService {
}
/**
* 默认为Singleton,相当于@Scope("singleton")
*/

(2)Prototype的Bean

//Prototype的Bean
@Service
@Scope("prototype")
public class ScopePrototypeService {
}
/**
* 每次调用新建一个Bean实例
*/

(3)配置类

//配置类
@Configuration
@ComponentScan("zhao.spring.com.SpringScope")
public class ScopeConfig {
}

(4)启动类

public class ScopeMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=
                new AnnotationConfigApplicationContext(ScopeConfig.class);

        //分别取两个Bean
        ScopeSingletonService s1=context.getBean(ScopeSingletonService.class);
        ScopeSingletonService s2=context.getBean(ScopeSingletonService.class);

        ScopePrototypeService p1=context.getBean(ScopePrototypeService.class);
        ScopePrototypeService p2=context.getBean(ScopePrototypeService.class);

        System.out.println("singleton的s1和s2:"+s1.equals(s2));
        System.out.println("prototype的p1和p2:"+p1.equals(p2));

        context.close();
    }
}

这里写图片描述

二、Spring EL

Spring表达式语言,支持在xml和注解中使用表达式,类似于JSP的EL表达式语言。
Spring开发中经常涉及调用各种资源的情况,包含普通文件、网址、配置文件、系统环境变量,我们可以使用Spring的表达式语言实现资源的注入。
Spring主要在注解@Value的参数中使用表达式。
1,示例
(1)增加commons-io可简化文件相关操作,这里使用commons-io将file转换成字符串。

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

新建text.txt,内容为:
这是一个txt文件
新建test.properties等待测试的配置文件
book.author=zhaoxudong
book.name=springbook
以上两个文件的存放位置:
这里写图片描述
为什么要存放在这里呢?
因为classpath的位置指向:
这里写图片描述
(2)需注入的Bean

//演示需注入的Bean
@Service
public class SpringELService {
    @Value("其他类的属性")
    private String another;

    public String getAnother() {
        return another;
    }

    public void setAnother(String another) {
        this.another = another;
    }
}
/**
* 这里注入了一个普通字符串
*/

(3)配置类

//配置类
@Configuration
@ComponentScan("com.zhao.spring.SpringEL")
//注入配置文件
@PropertySource("classpath:com/zhao/spring/SpringEL/test.properties")
public class SpringELConfig {
    //注入普通字符串
    @Value("this is normal")
    private String normal;
    //注入操作系统属性
    @Value("#{systemProperties['os.name']}")
    private String osName;
    //注入表达式结果
    @Value("#{ T(java.lang.Math).random()*100.0}")
    private double randomNumber;
    //注入其他Bean属性
    @Value("#{springELService.another}")
    private String fromAnother;
    //注入文件资源
    @Value("classpath:/com/zhao/spring/SpringEL/text.txt")
    private Resource testFile;
    //注入网址资源
    @Value("http://www.baidu.com")
    private Resource testUrl;

    /*
    注入配置文件
     */
    @Value("${book.name}")
    private String bookName;

    @Autowired
    private Environment environment;
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
        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 (IOException e) {
            e.printStackTrace();
        }
    }
}
/**
* 注入配置文件需要使用@PropertySource指定文件地址,若使用@Value注入,则需要配置一个PropertySourcesPlaceholderConfigurer
* 的Bean。
* 注入PropertySource还可以从Environment中获得
*/

(4)启动类

//启动类
public class SpringELMain {
    public static void main(String[] args) {

        AnnotationConfigApplicationContext context=
                new AnnotationConfigApplicationContext(SpringELConfig.class);

        SpringELConfig springELConfig=context.getBean(SpringELConfig.class);

        springELConfig.outputResource();
        context.close();
    }
}

这里写图片描述

三、Bean的初始化和销毁

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

1.演示
(1)增加JSR250支持

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

(2)使用@Bean形式的Bean

public class BeanWayService {
    public void init(){
        System.out.println("@Bean--init-method");
    }
    public BeanWayService() {
        System.out.println("初始化构造函数--BeanWayService");
    }
    public void destroy(){
        System.out.println("@Bean--destroy-method");
    }
}

(3)使用JSR250形式的Bean

@Service
public class JSR250WayService {
    @PostConstruct
    public void init(){
        System.out.println("JSR250--init-method");
    }
    public JSR250WayService() {
        System.out.println("初始化构造函数--JSR250WayService");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("JSR250--destroy-method");
    }
}
/**
 *  @PostConstruct 在构造函数执行完之后执行
 *  @PreDestroy 在Bean销毁之前执行
 */

(4)配置类

//配置类
@Configuration
@ComponentScan("com.zhao.spring.BeanInitDestroy")
public class BeanInitDestroyConfig {
    @Bean(initMethod = "init",destroyMethod = "destroy")
    BeanWayService beanWayService(){
        return new BeanWayService();
    }
}
/**
 * initMethod和destroyMethod指定BeanWayService类的init和destroy方法在构造之后、Bean销毁之前执行
 */

(5)启动类

public class BeanInitDestroyMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=
                new AnnotationConfigApplicationContext(BeanInitDestroyConfig.class);

        BeanWayService beanWayService=context.getBean(BeanWayService.class);
        JSR250WayService jsr250WayService=context.getBean(JSR250WayService.class);

        context.close();
    }
}

这里写图片描述