一、Bean的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实例
示例如下
//Prototype的bean类
package service.scope;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
//Prototype:每次调用新建一个Bean实例
@Scope("prototype")
public class DemoPrototypeService {}
//Singleton类
package service.scope;
import org.springframework.stereotype.Service;
@Service
//默认@Scope("Singleton"),Singleton:一个Spring容器只有一个Bean实例,此为Spring默认配置,全容器共享一个实例
public class DemoSingletonService {}
//配置类
package service.scope;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.scope")
public class ScopeConfig {}
//测试类
package service.scope;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
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);
System.out.println("s1与s2是否相等:"+(s1==s2));//true
DemoPrototypeService p1=context.getBean(DemoPrototypeService.class);
DemoPrototypeService p2=context.getBean(DemoPrototypeService.class);
System.out.println("p1与p2是否相等:"+(p1==p2));//false
}
}
二、Spring EL 与资源调用
spring EL 也就是Spring表达式语言,支持在xml和注解中使用表达式,类似于JSP的EL表达式语言。
Spring开发中我们可能经常涉及到调用各种资源的情况,包含普通文件、网址、配置文件、系统环境变量等,我们可以使用Spring的表达式语言实现资源的注入。
Spring主要在注解@Value的参数中使用表达式。如:
1、注入普通的字符串
2、注入操作系统属性
3、注入表达式运算结果
4、注入其他Bean的属性
5、注入文件内容
6、注入网址内容
7、注入属性文件
示例如下:
//需被注入的bean
package service.elspring;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
@Value("其他类的属性")
private String another;
public String getAnother() {
return another;
}
public void setAnother(String another) {
this.another = another;
}
}
//演示配置类
package service.elspring;
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;
/*
* 演示配置类
*/
@Configuration
@ComponentScan("service.elspring")
@PropertySource("classpath:service/elspring/test.properties")
public class ElConfig {
@Value("I Love You!") //注入普通字符串
private String normal;
@Value("#{systemProperties['os.name']}") //注入操作系统属性
private String osName;
@Value("#{ T(java.lang.Math).random() * 100.0 }") //注入表达式结果
private double randomNumber;
@Value("#{demoService.another}") //注入其他bean属性
private String fromAnother;
@Value("classpath:service/elspring/test.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 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的初始化和销毁
实际开发中经常遇到在Bean在使用之前或者之后做些必要的操作,Spring对Bean的生命周期的操作提供了支持,在使用java配置和注解配置下提供如下两种方式:
1、Java配置方式:使用@Bean的initMethod和destoryMethod(相当于xml配置的init-method和destory-method)
2、注解方式:利用JSR-250的@PostConstruct和@PreDestroy
示例如下:
package service.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");
}
}
package service.prepost;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
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");
}
}
package service.prepost;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.prepost")
public class PrePostConfig {
@Bean(initMethod="init",destroyMethod="destroy") //1
BeanWayService beanWayService(){
return new BeanWayService();
}
@Bean
JSR250WayService jsr250WayService(){
return new JSR250WayService();
}
}
package service.prepost;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
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();
}
}
四、事件
Spring的事件为Bean与Bean之间的消息通信提供了支持。当一个Bean处理完一个任务之后,希望另一个Bean知道并能做相应的处理,这时我们呢就需要让另一个Bean监听当前Bean所发送的事件。
Spring的事件需要遵循如下流程:
1、自定义事件,集成ApplicationEvent.
2、定义事件监听器,实现ApplicationListener
3、使用容器发布事件
示例:
//自定义事件
package service.event;
import org.springframework.context.ApplicationEvent;
/*
* 自定义事件
*/
public class DemoEvent extends ApplicationEvent{
private static final long serialVersionUID = 1L;
private String msg;
public DemoEvent(Object source,String msg) {
super(source);
// TODO Auto-generated constructor stub
this.msg=msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
//事件监听器
package service.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/*
* 事件监听类
*/
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
@Override
public void onApplicationEvent(DemoEvent event) {
// TODO Auto-generated method stub
String msg=event.getMsg();
System.out.println("我bean-demoListener接收到了"+"bean-demopublic的信息"+msg);
}
}
//事件发布类
package service.event;
/*
* 事件发布类
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;
public void publisher(String msg){
applicationContext.publishEvent(new DemoEvent(this,msg));
}
}
//配置类
package service.event;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.event")
public class EventConfig {}
//测试类
package service.event;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(EventConfig.class);
DemoPublisher demoPublisher=context.getBean(DemoPublisher.class);
demoPublisher.publisher("hello appliaction event");
context.close();
}
}
maven的pom.xml配置文件如下:
<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/maven-v4_0_0.xsd">
<!--声明项目描述符遵循哪一个POM模型版本。这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。-->
<modelVersion>4.0.0</modelVersion>
<!--父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。 坐标包括group ID,artifact ID和 version。-->
<parent>
<!--被继承的父项目的构件标识符-->
<groupId>org.springframework.boot</groupId>
<!--被继承的父项目的全球唯一标识符-->
<artifactId>spring-boot-starter-parent</artifactId>
<!--被继承的父项目的版本-->
<version>1.3.5.RELEASE</version>
<!--父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。Maven首先在构建当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativePath位置),然后在本地仓库,最后在远程仓库寻找父项目的pom。-->
<relativePath></relativePath>
</parent>
<!--项目的唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.mycompany.app生成的相对路径为:/com/bocom-->
<groupId>com.bocom</groupId>
<!--构件的标识符,它和group ID一起唯一标识一个构件。换句话说,
你不能有两个不同的项目拥有同样的artifact ID和groupID;在某个特定的group ID下,artifact ID也必须是唯一的。
构件是项目产生的或使用的一个东西,Maven为项目产生的构件包括:JARs,源码,二进制发布和WARs等。-->
<artifactId>testmaven</artifactId>
<!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型-->
<packaging>war</packaging>
<!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号-->
<version>0.0.1-SNAPSHOT</version>
<!--项目的名称, Maven产生的文档用-->
<name>testmaven Maven Webapp</name>
<!--项目主页的URL, Maven产生的文档用-->
<url>http://maven.apache.org</url>
<!--项目的详细描述, Maven 产生的文档用。 当这个元素能够用HTML格式描述时(例如,CDATA中的文本会被解析器忽略,就可以包含HTML标签), 不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,你应该修改你自己的索引页文件,而不是调整这里的文档。-->
<description>A maven project to study maven and boot</description>
<!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
</dependencies>
<build>
<finalName>testmaven</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin </artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>