Day 3
@Value
@Value注解用于设置需要注入容器的Bean的值,使用方法有以下三种:
- 基本数值
- 可以写SpEL,#{}
- 可以通过${}取出配置文件中的值(在运行环境变量里面的值)
要读取配置文件,需要在配置类上方添加@PropertySource(value = {“classpath:/person.properties”},encoding = “gbk”)注解读取配置文件
具体用法如下
@Component
public class Person {
@Value("32")
private int age;
@Value("lym")
private String name;
@Value("${nickName}")
private String nickName;
//constructor,setter,getter.
}
//nickName为读取配置文件中key为nickName的值
@PropertySource(value = {"classpath:/person.properties"},encoding = "gbk")
@Configuration
public class MainConfigPropertyValues {
@Bean
public Person person(){
return new Person();
}
}
@Autowired
@Autowired的简单使用
该注解实现自动注入。
- 默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);
- 如果找到多个类型的组件,再将属性的名称作为组件id去容器中查找。
- @Qualifier()注解可以指定需要装配的组件id
- 在自动装配的时候要讲需要装配的对象加入IOC容器,否则会报错,可以通过@Autowired(require=false)来取消这一限制
- 装配时可以通过@Primary来指定自动装配式默认的首选bean,他和@Qualifier()不能共存
下面通过代码解释
//配置类如下
@Configuration
@ComponentScan({"com.lym.controller","com.lym.service","com.lym.dao","com.lym.bean"})
public class MainConfigAutowired {
@Primary
@Bean(value = "bookDao1")
public BookDao bookDao(){
BookDao bookDao = new BookDao();
bookDao.setLabel("2");
return bookDao;
}
}
//该IOC容器有两个类型为BookDao的组件,一个为手动配置的,另外一个式有@CompomentScan扫描进入的。
@Repository
public class BookDao {
private String label = "1";
public String getLabel()
return label;
public void setLabel(String label)
this.label = label;
@Override
public String toString() {
return "BookDao{" +
"label='" + label + '\'' +
'}';
}
}
//在Service中我们需要bookDao对象,如果我们按照目前的设置,那么手动载入IOC容器的bean将会被注入到下面的bookDao2中。
public class BookService {
//@Qualifier("bookDao")
//@Autowired(required = false)
BookDao bookDao2;
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao2 +
'}';
}
}
@Autowired可以标注在属性上方,setter方法上方,也可以标注在构造器上方。在配置类中@Bean中的方法中的参数,也可以在创建对象的时候,从IOC容器中去获取相应的对象
//@Autowired(required = false)
BookDao bookDao2;
@Autowired
public void setBookDao2(BookDao bookDao2) {
this.bookDao2 = bookDao2;
}
@Configuration
@ComponentScan({"com.lym.controller","com.lym.service","com.lym.dao","com.lym.bean"})
public class MainConfigAutowired {
//被@Bean注解标注的方法中的参数也会从IOC容器中寻找对应的组件生成对象。
@Bean
public Color color(Car car){
Color color = new Color();
color.setCar(car);
return color;
}
}
@Autowired原理
待
@Resource与@Inject
这两个注解与@Autowired作用大体相同,但是他们相比@Autowired有一些功能上的缺失,对比见下表
@Autowired | @Resource | @Inject | |
---|---|---|---|
注解归属 | Spring | java规范 | java规范 |
require功能 | 支持 | 不支持 | 不支持 |
@Primary功能 | 支持 | 不支持 | 支持 |
@Quelifier功能 | 支持 | 待实验 | 待实验 |
自定义组件功能扩展
如果自定义组件希望获得Spring容器底层的一些组件,那么需要实现相应的方法,比如如果先过的Spring的ApplicationContext,那么他需要实现ApplicationContextAware接口。Aware接口的功能时通过后置处理器实现的。
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware {
private StringValueResolver stringValueResolver;
private String driver;
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.stringValueResolver = resolver;
this.driver = stringValueResolver.resolveStringValue("${db.drive}");
}
}
@Profile
我们在开发过程中,会设计到很多环境,Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能。
我们在配置类中的@Bean方法上去添加@Profile注解,该注解会指定组件在哪个环境的情况下才能被注册到容器中,不指定任何环境都能注册该组件,该注解既可以标注在方法上,也可以标注在类文件上,只有在指定的环境的时候,所标注的类或者方法代表的Bean才会被加载
指定环境有两种方法:
- 通过命令行参数指定环境
- 通过代码的方式指定环境
// 1. 通过 -Dspring.profiles.active=test 可以指定
// 2
public void test01(){
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext();
applicationContext.getEnvironment().setActiveProfiles("dev");
applicationContext.register(MainConfigOfProfile.class);
applicationContext.refresh();
String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);
for(String s : namesForType) System.out.println(s);
}