Spring 常用配置

Bean 的 Scope

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实例。
    另外,在Spring Batch中还有一个Scope 是使用@StepScope。

示例来演示Singleton和Prototype,分别从Spring容器中获得2次的Bean,判断Bean的实例是否相等。

  • 编写Singleton的Bean
@Service 
//不指定默认为Singleton,相当于@Scope("sigleton")。
public class DemoSingletonService{

}
  • 编写Prototype的Bean
@Service 
@Scope("prototype")//声明Scope为Prototype
public class DemoPrototypeService{

}
  • 配置类
@Configuration
@ComponentScan("com.cn.lr.scope")
public class ScopeConfig{

}
  • 运行
public class Main{
	public static void main(String [] args){
		AnnotationConfigApplicationContext context = 
			 new AnnotationConfigApplicationContext();
	 
		DemoPrototypeService p1 = 
			new DemoPrototypeService();
		DemoPrototypeService p2 = 
			new DemoPrototypeService();
 
		DemoSingletonService s1 = 
			new DemoSingletonService();
		DemoSingletonService s2 = 
			new DemoSingletonService();

		 System.out.println("s1与s2是否相等:"+
			 s1.equals("s2"));
		 System.out.println("p1与p2是否相等:"+
			 p1.equals("p2"));
 
		 context.close();
	}
 
}
  • 结果

s1与s2是否相等:true
p1与p2是否相等:false


Spring EL 和资源调用

Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于JSP的EL表达式语言。
Spring开发中经常涉及调用各种资源的情况,包含普通文件、网址、配置文件、系统变量等,我们可以使用Spring的表达式语言实现资源的注入。
Spring 主要在注解@Value 的参数中使用表达式。

@Configuration
@ComponentScan("com.cn.lr.el")
@PropertySource("classpath:com/cn/lr/el/test.properties") //7
public class ElConfig{

	//注入普通字符
	@Value("I am lr") 
	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:com/cn/lr/el/test.txt") 
	private Resource testFile;
	
	//注入网址资源
	@Value("http://www.baidu.com") 
	private Resource testUrl;

	//7
	@Value("${book.name}") 
	private String bookName;
	
	//7
	@Autowired
	private Environment environment;

	//7
	@Bean
	public static PropertySourcesPlaceholderConfigurer         propertyConfigure(){
	return new PropertySourcesPlaceholderConfigurer();
	}
}

解析注解7:注入配置文件需要使用@PropertySource指定文件地址,若使用@Value注入,则要配置一个PropertySourcesPlaceholderConfigurer的Bean。注意,@Value("\${book.name}")使用的是"$",而不是"#"。

注入Properties还可以从Environment中获得。environment.getProperty(key);


Bean的初始化和销毁

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

  • 使用@Bean形式的Bean。
public class BeanWayService{

	public void init(){
		System.out.println("@Bean-init-method");
	}
	public BeanWayService(){
		super();
		System.out.println("初始化构
		造函数-BeanWayService");
	}
	public void destory(){
		System.out.println("@Bean-destory-method");
	}
	
}
  • 使用JSR250形式的Bean。
//首先在项目中添加JSR250支持
//<dependency>
//<groupId>javax.annotation</groupId>
//<artifactId>jsr250-api</artifactId>
//<version>1.0</version>
//</dependency>

public class JSR250WayService{

	@PostConstruct //在构造函数执行完成之后执行
	public void init(){
		System.out.println("jsr250-init-method");
	}
	public JSR250WayService(){
		super();
		System.out.println("初始化构
		造函数-JSR250WayService");
	}
	@PreDestory //在Bean销毁之前执行
	public void destory(){
		System.out.println("jsr250-destory-method");
	}
	
}
  • 配置类
@Configuration
@ComponentScan("com.cn.lr.prepost")
public class PrePostConfig{
	
	//initMethod和destoryMethod指定BeanWayService类的
	//init和destory方法在构造之后、Bean销毁之前执行。
	@Bean(initMethod="init",destoryMethod="destory")
	BeanWayService beanWayService(){
		return new BeanWayService();
	}
	
	@Bean
	JSR250WayService jsr250WayService(){
		return new JSR250WayService();
	}
}
  • 运行
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();
	}
}
  • 结果

初始化构造函数-BeanWayService
@Bean-init-method
初始化构造函数-JSR250WayService
jsr250-init-method
程序关闭后:
jsr250-destory-method
@Bean-destory-method


Profile

profile 为在不同环境下使用不同的配置提供了支持(开发环境下的配置和生产环境下的配置肯定是不同的,例如,数据库的配置)。

  1. 通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。在开发中使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。
  2. 通过设定jvm的spring.profiles.active参数来设定配置环境。
  3. Web项目设置在Servlet的context parameter中。
  • Servlet 2.5 及以下:
<servlet>
	<servlet-name>dispatcher</servlet-name>
	<servlet-class>org.springframework.web.servlet.Di
		spatcherServlet</servlet-class>
	<init-param>
		<param-name>spring.profiles.active</param-name>
		<param-value>production</param-value>
	</init-param>
</servlet>

  • Servlet 3.0 及以上:
public class WebInit implements
	WebApplicationInitializer{

	public void onStartup(ServletContext container) 
		throws ServletException{
		
		container.setInitParameter("spring.profiles.
			default", "dev");
			
	}
}
  • 注解
    @Profile

示例Bean。

public class DemoBean{
	private String content;

	public DemoBean(String content){
		super();
		this.content = content;
	}
	//省略 getter setter 方法
}

Profile 配置

@Configuration
public class ProfileConfig{
	
	@Bean
	@Profile("dev")//Profile为dev时实例化devDemoBean
	public DemoBean devDemoBean(){
	  return new DemoBean("from development profile");
	}
	
	@Bean
	@Profile("prod")//Profile为prod时实例化prodDemoBean
	public DemoBean prodDemoBean(){
	  return new DemoBean("from production profile");
	}
}

运行

public class Main{
	public static void main(String [] args){
		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();
	}
}

结果

from production profile

将context.getEnvironment().setActiveProfiles(“dev”);效果则是:
from development profile


事件(Application Event)

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

  1. 自定义事件,继承ApplicationnEvent
  2. 定义事件监听器,实现ApplicationListener。
    3.使用容器发布事件
  • 自定义事件
public class DemoEvent extends ApplicationEvent{
  private static final long serialVersionUID = 1L;
  private String msg;
  public DemoEvent(String msg){
	  super();
	  this.msg = msg;
  }
  //省略 getter setter 方法
}
  • 事件监听器
@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);
	}
}
//1:实现ApplicationListener接口,并指定监听的事件类型
//2:使用onApplicationEvent方法对消息进行接收处理。
  • 事件发布类
@Component
public class DemoPublisher{
	
	//注入ApplicationContext用来发布事件
	@Autowired
	ApplicationContext applicationContext;
	
	public void publish(String msg){
		//使用ApplicationnContext的publishEvent方法来发布
		ApplicationContext.publishEvent(new
			DemoEvent(this, msg));
	}
}

  • 配置类
@Configuration
@ComponentScan("com.cn.lr.event")
public class EventConfig{

}
  • 运行
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();
	
  }
  
}
  • 结果
    我(bean-demoListener)接收到了bean-demoPublisher发布的消息:hello application event

Spring 的java配置方式

Java配置是Spirng4.x推荐的配置方式,可以完全替代xml配置
@Configuration 和 @Bean 这两个注解实现的。
@Configuration 作用于类上,相当于一个xml配置文件
@Bean 作用于方法上,相当于xml配置中的
容器使用的是AnnotationConfigApplicationContext

配置类
创建spring容器

Spring读取外部的资源配置文件

通过@propertySource可以指定读取的配置文件,通过@Value注解取值。
ps:@PropertySource(Value={“classpath:jdbc.properties”})
@Value("${jdbc.url}")
如果有多个配置文件,怎么办?
可写多个。@PropertySource(Value={“classpath:jdbc.properties”,“xx”,“xxx”})
如果配置文件不存在,怎么办?
ignoreResourceNotFount=true 忽略不存在的。
@PropertySource(Value={“classpath:jdbc.properties”,“xx”,“xxx”},ignoreResourceNotFount=true)

Spring加载xml配置

通过spring提供的@ImportResource来加载xml配置。例如:@ImportResource({“classpath:some-context.xml”,“classpath:another-context.xml”})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值