spring02

 
spring重新整理归纳——装配bean02
线索Cues
笔记Notes
  • 配置profile
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 激活profile
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 条件化装配
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 自动装配的歧义性
 
当使用这个注解组合时,实例的名称是不是改写了?
@Component
@Qualifier("cold")
 
 
 
 
 
 
 
 
 
  • Bean的作用域
 
 
 
 
 
 
 
 
  • 环境
在实际项目中,我们可能会用到不同的环境,例如测试环境对应的数据库和正式环境对应的数据库肯定是有区别的,spring提供了一套机制能够根据不同的环境装配不同的Bean
 
@Profile 注解,这个注解在spring3.1中只能支持类上的注解,在之后的版本中支持注解方法,而没有被特别加上这个注解的类无论哪个环境都会被创建
 
 
还可以在xml使用环境配置
 
 
当设置好之后,spring需要确定哪一个配置被激活需要spring.profiles.active和spring.profiles.default这两个独立的属性激活,首先会找到active属性,如果active没有被设置,那么回去找default属性,如果default属性也没有被设置,那么spring只会创建那些没有@Profile注解的方法和对象。
 
这两个属性和使用很多种方式进行激活:
  1. 作为DispatcherServlet的初始化参数
  2. 作为web应用的上下文
  3. 在测试的时候使用@ActiveProfiles注解
 
作为DispatcherServlet的初始化参数
<servlet>
<servlet-name>chapter02</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>chapter02</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
 
作为web应用的上下文
<context-param>  
   <param-name>spring.profile.default</param-name>  
   <param-value>dev</param-value>  
</context-param>
 
在测试的时候使用@ActiveProfiles注解
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= DataSourceConfig.class)
@ActiveProfiles("dev")
public static class DevDataSourceTest {
 
@Autowired
private DataSource dataSource;
 
 
@Test
public void shouldBeEmbeddedDatasource() {
assertNotNull(dataSource);
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() {
 
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getLong("id") + ":" + rs.getString("name");
 
}
});
 
 
assertEquals(1, results.size());
assertEquals("1:A", results.get(0));
}
}
 
 
  • 条件化装配
 
在实际项目我们可能会遇到一个或多个Bean只有包含某些特定类或者需要设置某个特定环境变量的时候才创建,这时候就要用到@Conditional注解,这个注解可以根据条件判断是否创建改对象,该注解可以用到@Bean注解的方法上,也就是说适用于javaconfig配置类中。
 
新建一个java配置类,并且新建一个方法,并且添加@Conditional注解,并且在参数中指定一个条件类。
 
 
@Configuration
public class MagicConfig {
 
@Bean
@Conditional(MagicExistsCondition.class)
public MagicBean magicBean() {
return new MagicBean();
}
}
 
这个条件类就是用来判断是否需要生成对象的类,它必须实现org.springframework.context.annotation.Condition接口,这个接口非常的简单,只需要实现match方法,返回true生成对象,false不生成。
 
public class MagicExistsCondition implements Condition {
 
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
return env.containsProperty("magic");
}
}
 
context表示程序的上下文,Environment代表当前的环境,当前环境有名为magic属性就创建magincBean对象。
 
书上还提到@Profile注解也使用了@Conditional注解,并且使用了ProfileCondition作为条件类。
 
 
 
  • 限定自动装配Bean
当使用@Autowired的时候,有可能会遇到多个匹配对象,这时候可以使用@Qualifier注解来指定自动装配的对象。
 
@Autowired
@Qualifier("iceCream")
 
参数为使用@Component注解创建的对象,如果想要自定义限定符的话,需要和@Component注解一起使用
 
@Component
@Qualifier("cold")
 
 
 
  • bean的作用域
spring默认对象为单例模式,当要指定对象为其他模式时,可以使用@Scope注解,这个注解和@Component一起使用,当传入不同的参数时表现出不同的作用。详解下面的表格。
值得注意的是当使用会话和请求模式的时候,由于会话和请求不会在程序一开始就运行,所以委托给代理类,当被代理类是接口时,使用proxyMode = ScopedProxyMode.INTERFACES指定基于接口生成代理类,当被代理类是类时,使用proxyMode = ScopedProxyMode.TARGET_CLASS基于类进行生成代理类。
 
 
 
  • 运行时注入值
当讨论依赖注入的时候,很多时候会使用硬解码的方式来处理一些值,但是有时候会想要这些值在运行时确定,我们可以通过@PropertySource注解指定外部数据源,例如在编写配置类的时候这些可以自动注入Environment对象,这个对象保存着spring运行时的配置参数,可以通过它获取我们指定的外部数据源里的数据,
 
 
除此之外,还可以指定默认值
值得注意的是,如果想要转换数据类型,spring提供对应的重载方法
 
 
还可以通过Environment对象获取激活和默认的配置
 
 
 
  • spring中的占位符
 
spring能够使用@value注解调用外部的数据源,详情看表格
 
  • springEL表达式
 
 
 
 
 
总结Summary
  • 记录最重要几点
  • 写成可以快速检索形式
  • 课后复习总结
 
 
 
@Profile
@Profile("dev")
注解环境,参数为环境名字
@ActiveProfiles
@ActiveProfiles("dev")
测试环境下激活profile,参数为环境名称
@Conditional
@Conditional(xxx.class)
创建对象的条件,参数为 条件类
@Primary
 
当使用@Autowired匹配到多个对象时,能够避免歧义
@Qualifier
@Autowired
@Qualifier("iceCream")
当和@Autowired一起使用的时候会将名字为参数的对象注入到对象中
 
@Component
@Qualifier("cold")
当和@Component一起使用的时候便是指定类的名字
@Scope
 
指定对象生成时的作用域,默认为单例模式
 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)  指定类为单例模式
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)  指定类为原型模式,每次运行都会创建一个新的实例
@Scope(value = WebApplicationContext.SCOPE_SESSION,proxyMode = ScopedProxyMode.INTERFACES)指定类为会话模式,每个会话都会创建一个新的实例
@Scope(value = WebApplicationContext.SCOPE_REQUEST,proxyMode = ScopedProxyMode.INTERFACES)指定类为请求模式,每个请求创建一个新的实例
 
@value
@Component
public class ValueDemo {
@Value("${jdbc.driverClass}")
private String driver;
能够使用占位符注入spring环境中的变量
<context-param>
 
作用:该元素用来声明应用范围(整个WEB项目)内的上下文初始化参数。param-name 设定上下文的参数名称。必须是唯一名称。param-value 设定的参数名称的值
 
 
 
 
 
posted @ 2019-05-06 18:47  qunincey  阅读(106)  评论(0编辑  收藏  举报