上篇文章介绍 的是spring底层对BeanPostProcessor的使用,今天介绍一下bean属性的赋值和自动装配
@Value注解
可以写直接的数值
也可以使用SPEL表达式#{ }
$ {}去取配置文件中的值${}去除配置文件中的值
在根目录下创建一个person.properties
ZHANSAN.name=false
创建配置类
@Configuration
//使用@PropertySource注解将配置文件的k/v导入到运行时环境中,为Bean属性赋值,可以重复使用,导入多个配置文件
@PropertySource({"classpath:/person.properties"})
public class TestValueAndPropertyConfig {
@Bean
public Person person(){
return new Person();
}
}
创建bean
public class Person {
//可以写直接的数值
@Value("${ZHANSAN.name}")
private String name;
//可以写直接的数值
@Value("10")
private Integer age;
//@Value("${ZHANSAN.SEX}")
private Boolean sex;
public Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
@Autowired注解可以加在方法上 构造器上 类上 参数上
该注解优先按照类去IOC中找到需要的组件,如果IOC中同一类型的组件有多个,就按照属性名去注入,可以使用@Qualifier注解指定要注入的组件的id,而不是默认的使用属性名,如果容器中没有要注入的组件,可以是设置@Autowired的required值为true,表示注入的时候,该bean必须存在,否则就会注入失败,会报错。required值为false表示没有改组件时IOC容器忽略掉这个注入,不报错。此外可以再要注入的组件中添加@Primary注解,表示这个组件是首选的组件,在以后的注入中会以这个组件优先。
创建需要的的接口和实现
public interface BookService {
void printBookName();
}
@Service("javaJvm")
public class JavaJVM implements BookService {
public void printBookName() {
System.out.println("this is book named Java Jvm");
}
}
//@Primary
@Service("thinkingInJava")
public class ThinkingInJava implements BookService {
public void printBookName() {
System.out.println("this is book named Thinking In Java");
}
}
@Configuration
@ComponentScan(value = {"com.wmq.spring.testautoWiredandqualifier"})
public class TestAotuWiredAndQualifierConfing {
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestAotuWiredAndQualifierConfing.class})
public class TestautoWiredandqualifier extends BasedSpringTest {
@Autowired
@Qualifier("thinkingInJava")
private BookService thinkingInJava;
//默认就是@Autowired(required=true),表示注入的时候,该bean必须存在,否则就会注入失败。
@Autowired(required=false)
@Qualifier("javaJvm")
private BookService javaJvm;
@Test
public void testAotuWiredAndQualifier(){
thinkingInJava.printBookName();
javaJvm.printBookName();
}
}
测试结果
this is book named Thinking In Java
this is book named Java Jvm
在ThinkInJava上加上@Primary注解,去掉注入时的@Qualifier注解测试结果如下,这就说明这时的注入跟属性名没有关系了,直接注入ThinkInJava组件,测试结果如下
this is book named Thinking In Java
this is book named Thinking In Java
1、@Autowired是spring自带的注解,通过‘AutowiredAnnotationBeanPostProcessor’ 类实现的依赖注入;
2、@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier;
3、@Autowired有个属性为required,可以配置为false,如果配置为false之后,当没有找到相应bean的时候,系统不会抛错;
4、@Autowired可以作用在变量、setter方法、构造函数上。
1、@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject;实现注入。
2、@Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named;
3、@Inject可以作用在变量、setter方法、构造函数上。
1、@Resource是JSR250规范的实现,需要导入javax.annotation实现注入。
2、@Resource是根据名称进行自动装配的,一般会指定一个name属性
3、@Resource可以作用在变量、setter方法上。
1、@Autowired是spring自带的,@Inject是JSR330规范实现的,@Resource是JSR250规范实现的,需要导入不同的包
2、@Autowired、@Inject用法基本一样,不同的是@Autowired有一个request属性
3、@Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的
4、@Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用
指定组件在哪个环境下才能被注入到容器中,默认是default环境
dbconfig.properties
user.name=root
user.password=123456
user.driverclass=com.mysql.jdbc.Driver
配置类
@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class TestProfileConfig {
@Value("$user.name")
private String userName;
@Value("$user.password")
private String userPassword;
@Value("$user.driverclass")
private String driverClass;
@Profile("test")
@Bean
public DataSource dataSourceTest() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(userName);
dataSource.setPassword(userPassword);
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("dev")
@Bean
public DataSource dataSourceDev() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(userName);
dataSource.setPassword(userPassword);
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/taobao");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("Prod")
@Bean
public DataSource dataSourceProd() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(userName);
dataSource.setPassword(userPassword);
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/quartz");
dataSource.setDriverClass(driverClass);
return dataSource;
}
}
编写测试类,因为这里不知道怎么用idea设置jvm的启动参数,故自己仿照applicationContext的有参构造来设置容器的运行时环境
@Test
public void testProfile(){
//创建一个applicationContext
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
//设置容器的运行环境
ConfigurableEnvironment environment = applicationContext.getEnvironment();
environment.setActiveProfiles("test");
//注册容器
applicationContext.register(TestProfileConfig.class);
//刷新容器
applicationContext.refresh();
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
dataSourceTest
可以自己设置其他的环境试试
此外@Profile注解还可以写在配置类上,当写在配置类上时只有处在指定环境下,才会在IOC中加入bean
属性赋值和自动装配介绍完毕,接下来将介绍AOP的使用和原理