Spring笔记(高级装配)

1 @profile 注解

1.1 JavaConfig 配置

@profile 注解在 Spring 中用于根据 环境 决定某个 bean 是否应该被创建。
通常的,@profile 注释应用在类级别上,如下代码,它会告诉 Spring 这个名叫 DevelopmentProfileConfig 配置类中的 bean 只有在 dev profile 激活的时候才会创建。

@Configuration
@Profile("dev")
public class DevelopmentProfileConfig {
	@Bean
	public DataSource dataSource() {
		return new EmbeddedDatabaseBuilder();
	}
}

1.2 XML 配置

XML 配置使用 @Profile 注解则是在 <beans> 元素中声明属性 profile,如:

<beans profile="dev" ...>
	....
</beans>

1.3 激活 profile

Spring 在确定哪个 profile 处于激活状态的时候,需要依赖两个独立的属性:

  • spring.profiles.active
  • spring.profiles.default

即如果没有设置 active 值时,默认会取 default 值,如果二者都没有设置,那么就没有激活的 profile,因此只会创建那些没有定义在 profile 中的bean。
有多种方式来设置这两个属性,以下举出常用的两种形式:

  • 作为 DispatcherServerlet 的初始化参数:
  • 作为 Web 应用的上下文参数

即在 Web 应用中的 web.xml 文件中设置 profile,在该 xml 文件中添加以下元素:

<!-- 为上下文设置默认的 profile -->
<context-param>
	<param-name>spring.profiles.default</param-name>
	<param-value>dev</param-value>
</context-param>

<!-- .... -->

<!-- 为 Servlet 设置默认的 profile -->
<servlet>
	<servlet-name>appServlet</servlet-name>
	<servlet-class>
		org.springframework.web.servlet.DispatcherServlet
	</servlet-class>
	<!-- 为 Servlet 设置默认的 profile -->
	<init-param>
		<param-name>spring.profiles.default</param-name>
		<param-value>dev</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>

2 @Conditional

@Conditional 注释给定一个 class,它指明了条件,声明了此注释的 bean 。
该 class 实质是一个 Condition 接口的实现,Condition 接口实现只需提供 matches() 方法的实现即可,如果 matches 方法返回 true,那么就会创建带有 @Confitional 注解的 bean,否则将不会创建该 bean。
matches 方法有两个参数,分别是 ConditionContext 以及 AnnotatedTypeMetadata
ConditionContext 是一个接口,它有以下几个重要的方法:

  • getRegistry() 返回 BeanDefinitionRegistry 检查 bean 定义
  • getBeanFactory() 返回 ConfigurableListableBeanFactory 检查 bean 是否存在,甚至探查 bean 的属性
  • getEnvironment() 返回的 Environment 检查环境变量是否存在以及它的值是什么
  • getResourceLoader() 返回的 ResourceLoader 所加载的资源
  • getClassLoader() 返回的 ClassLoader 加载并检查类是否存在

AnnotatedTypeMetadata 同样是一个接口,它能够检查带有 @Bean 注解的方法上还有什么其他的注解。

eg:

public class MagicExistCondition implements Condition {
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		Environment env = context.getEnvironment();
		return env.containsProperty("magic");
	}
}

3 @ Qualifier

使用 @Autowired 注释实现自动装配的时候,默认的是按照类型进行自动装配,如果自动装配的时候出现多个相同的类型,就会报错了,此时可以使用 @Qualifier 注解进行依赖 ID 而不是类型的注入:

@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert) {
	this.dessert = dessert;
}

3.1 创建自定义的限定符

自动装配的时候,按照的 ID 是 bean 声明时候的类名,如果想要自定义 ID,可以在声明组件 bean 的时候添加 @Qualifier 注解

@Component
@Qualifier("iceCream")
public class IceCream {}

4 @Scope

在默认的情况下,Spring 引用上下文所有 bean 都是作为单利的形式创建的,也就是说,不管给定的 bean 被注入到其它的 bean 多少次,每次注入的都是同一个实例。

Spring 定义了多种作用域,可以基于这些作用域创建 bean,包括:

  • 单例(Singleton):在整个应用中,只创建一个实例
  • 原型(Prototype):每次注入或通过 Spring 应用上下文获取的时候,都会创建一个 bean 的实例
  • 会话(Session):在 Web 应用中,为每个会话创建一个 bean 实例
  • 请求(Request):在 Web 应用中,为每个请求创建一个 bean 实例

eg:

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad {
	....
}

5 @PropertySource

在 Spring 中,处理外部值得最简单方式就是声明属性源并通过 Spring 的 Environment 来检索属性。
@PropertySource 注解用于声明属性源,再通过 Environment 实例获取相应的属性值。
eg:

@Configuration
@PropertySource("classpath:/top/seiei/app.properties")
public class ExpresssiveConfig {
	@Autowired
	Environment env;

	@Bean
	public BlankDisc disc() {
		return new BlankDisc(
			env.getProperty("disc.title"),
			env.getProperty("disc.artist")
		);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值