Spring常用配置

Bean的Scope

简单讲解两个:

  1. Singleton:共享一个实例
  2. Prototype:每次调用新建一个实例

Singleton

@Service
public class SingletonService {
...
}

Scope默认为Singleton,所以不需要加@Scope(“singleton”)。

Prototype

@Service
@Scope("prototype")
public class PrototypeService {
...
}

配置类

@Configuration
@ComponentScan("需要扫描的包")
public class ScopeConfig {
...
}

运行

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);

SingletonService s1 = annotationConfigApplicationContext.getBean(SingletonService.class);

SingletonService s2 = annotationConfigApplicationContext.getBean(SingletonService.class);

PrototypeService p1 = annotationConfigApplicationContext.getBean(PrototypeService.class);

PrototypeService p2 = annotationConfigApplicationContext.getBean(PrototypeService.class);

System.out.println(s1.equals(s2));
System.out.println(p1.equals(p2));

结果:

  1. s1与s2相等
  2. p1与p2不相等

资源调用

@Value中的参数使用EL表达式,支持如下几种情况:

  1. 注入普通字符
  2. 注入操作系统属性
  3. 注入表达式运算结果
  4. 注入其他Bean的属性
  5. 注入文件内容
  6. 注入网址内容
  7. 注入属性文件
test.properties

book.name=spring
book.author=denyu
---
public class DemoService {
@Value("+++")
private String another;
getAnother()...;
setAnother()...;
}
---
@Configuration
@ComponentScan("需要扫描的包")
@PropertySource("classpath:xxx/xxx/test.properties")
public class ElConfig {
@Value("~~~")
private String normal;

@Value("#{systemProperties['os.name']}")
private String osName;

@Value("#{T(java.lang.Math).random() * 100.0}")
private String randomNumber;

@Value("#{demoService.another}")
private String fromAnother;

@Value("calsspath:xxx/xxx/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();
}

...
environment.getProperty("book.author")
}

使用@PropertySource指定文件地址,若用@Value注入,则需要配置一个PropertySourcesPlaceholderConfigurer的Bean。

注入Properties还可以从Environment中获得,详见代码的book.author的获取。

Bean的初始化和销毁

  1. Java配置方式
  2. JSR-250注解方式

Java配置

public class BeanWayService {
public void init() { ... }

public void destroy() { ... }
}

JSR250注解

public class JSR250WayService {
@PostConstruct
public void init() {}

@PreDestroy
public void destroy() {}
}
// pom.xml文件
<!--增加JSR250支持-->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>

配置类

@Configuration
@ComponentScan("...")
public class Config {
@Bean(initMethod="init", destroyMethod="destroy")
BeanWayService beanWayService() {
return new BeanWayService();
}

@Bean
JSR250WayService jsr250WayService {
return new JSR250WayService();
}
}

Java配置与JSR-250注解方式的效果是一样的。

init在类被构造后执行,destroy在类被销毁前执行。

Profile

可根据设置profile区分环境

public class DemoBean {
private String content;
public DemoBean(String content) {
this.content = content;
}
getContent()...
}

配置类

@Configuration
public class ProfileConfig {
@Bean
@Profile("dev")
public DemoBean devDemoBean() {
return new DemoBean("from dev");
}

@Bean
@Profile("prod")
public DemoBean prodDemoBean() {
return new DemoBean("from prod");
}
}

运行

AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();

context.getEnvironment().setActiveProfiles("prod");
context.register(ProfileConfig.class);
context.refresh();

DemoBean demoBean = context.getBean(DemoBean.class);
System.out.println(demoBean.getContent());
annotationConfigApplicationContext.close();
  1. 先将活动的Profile设置为prod
  2. 注册Bean的配置类
  3. 刷新容器

事件

  1. 自定义事件,继承自ApplicationEvent。
  2. 定义事件监听,实现ApplicationListener。
  3. 使用容器发布事件。

自定义事件

public class DemoEvent extends ApplicationEvent {
private String msg;

public DemoEvent(Object source, String msg) {
super(source);
this.msg = msg;
}

public String getMsg() {
return msg;
}
}

定义事件监听

@Component
public class DemoListener implements ApplicationListener<DemoEvent> {
@Override
public void onApplicationEvent(DemoEvent demoEvent) {
String msg = demoEvent.getMsg();

System.out.println("我(Listener)接收到了(Publisher)发布的消息:" + msg);
}
}

事件发布类

@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;

public void publish(String msg) {
applicationContext.publishEvent(new DemoEvent(this, msg));
}
}

配置类

省略

运行

...
demoPublisher.publish("hello ...");
...