第18小节:给属性赋值—@Value
写一个配置类:
创建一个方法:在这个方法中给容器中注入一个person实例
@Configuration
public class MainConfigOfPropertyValues {
@Bean
public Person person(){
return new Person();
}
}
测试方法:在该方法中获取到容器中的实例,同时获取容器中的该实例的属性值
public class IOCTest_PropertyValue {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
@Test
public void test01(){
printBeans(applicationContext);
System.out.println("===========================");
Person person= (Person) applicationContext.getBean(“person”);
System.out.println(person);
applicationContext.close();
}
private void printBeans(AnnotationConfigApplicationContext applicationContext) {
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
}
测试结果:
mainConfigOfPropertyValues
person
Person{name=‘null’, age=null}——属性没有被赋值
以前用配置的方式,在bean.xml中配置person类,用property标签配置属性
现在使用 注解的方式:使用@Value赋值
//1.基本数据
//2.可以写SpEL: #{ }(在运行环境变量里面的值)
//3.可以写${ }:取出配置[properties]文件中的值
在peron类中的各个属性上添加@Value
@Value(“雪梅”)
private String name;
@Value("#{20-2}")
private Integer age;
person类:
public class Person {
@Value(“雪梅”)
private String name;
@Value("#{20-2}")
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类不变
测试结果:
mainConfigOfPropertyValues
person
Person{name=‘雪梅’, age=18}——————————通过@Value注解给person类中的属性赋值完成
第19小节:给属性赋值—@PropertitySource加载外部配置文件
在person中添加一个属性nickName,getter和setter方法
测试类不变
测试结果:
mainConfigOfPropertyValues
person
Person{name=‘雪梅’, age=18, nickName='null’}———————nickName这个属性没有给它赋值,所以是null
写一个配置文件:person.properties
在其中配置nickName的值:person.nickName=“小张三”
若是在bean.xml中,给person类中的nickName属性赋值——这个值来自在person.propertity配置文件中的值
原来的方式:
需要在bean.xml中指定这个person.properties的位置:<context:property-placeholder location=“classpath:person.properties”/>
指定好这个配置文件的位置后:就可以在person类上用注解@Value中给属性赋值——这个值来自指定的配置文件的值
使用注解的方式:
在配置类上使用注解@PropertySource中导入配置文件
//使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中,加载完外部的配置文件以后使用${}取出配置文件的值
@PropertySource(value={“classpath:/person.properties”})
在person类的属性上使用@Value取配置文件中指定的该属性的值
@Value("${person.nickName}")
private String nickName;
测试类不变
测试结果:
mainConfigOfPropertyValues
person
Person{name=‘雪梅’, age=18, nickName=’“小张三”’} —————成功给该属性赋值
配置文件中的值都可以加载到容器中的环境变量中
在测试类中,获取运行时的环境变量:因为配置文件中的值默认都加载到了环境变量中
ConfigurableEnvironment environment=applicationContext.getEnvironment();
String property=environment.getProperty(“person.nickName”);
System.out.println(property);
@Test
public void test01(){
printBeans(applicationContext);
System.out.println("===========================");
Person person= (Person) applicationContext.getBean(“person”);
System.out.println(person);
ConfigurableEnvironment environment=applicationContext.getEnvironment();
String property=environment.getProperty(“person.nickName”);
System.out.println(property);
applicationContext.close();
}
测试结果:
mainConfigOfPropertyValues
person
Person{name=‘雪梅’, age=18, nickName=’“小李四”’}
“小李四”
第20小节:@Autowired@Qualifier@Primary
自动装配:Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值
1)@Autowired/;自动注入
1) 默认优先按照类型去容器中找对应的组件:applicationContext.getBean (BookDao.class)
2)如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找:applicationContext.getBean (“bookDao”)
3) @Qualifier(“bookDao”):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
4)自动装配默认一定要将属性赋值好,没有就会报错,也可以在@Autowired中指定required=flase,那就不是必须赋值了
5)@Primary :让spring进行自动装配的时候,默认使用首选的bean
也可以继续使用@Qualifier指定组要装配的bean的名字
BookService {
@Autowired
private BookDao bookDao;
写一个controller:在里面自动装配service
@Controller
public class BookController {
@Autowired
private BookService bookService;
}
写一个service:在里面自动装配dao
@Service
public class BookService {
@Autowired
private BookDao bookDao;
public void print(){
System.out.println(bookDao);
}
}
写一个dao
@Repository
public class BookDao {
}
写一个配置类:在该类上扫描上述几个组件
@Component
@ComponentScan({“com.atguigu.service”,“com.atguigu.dao”,“com.atguigu.controller”})
public class MainConfigOfAutowired {
}
编写测试类:在ioc容器拿到bookservice,看看是否自动注入成功
public class IOCTest_Autowired {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
@Test
public void test01(){
BookService bookService=applicationContext.getBean(BookService.class);
System.out.println(bookService);
}
}
测试结果:
BookService{bookDao=com.atguigu.dao.BookDao@de3a06f}———成功获取到容器中自动注入的对象
在测试类中直接从容器中获取dao,看看容器中的dao和在bookservice中通过自动装配注入的dao是否是同一个?
测试类:
public class IOCTest_Autowired {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
@Test
public void test01(){
BookService bookService=applicationContext.getBean(BookService.class);
System.out.println(bookService);
BookDao bean=applicationContext.getBean(BookDao.class);
System.out.println(bean);
}
}
测试结果:
BookService{bookDao=com.atguigu.dao.BookDao@de3a06f}
com.atguigu.dao.BookDao@de3a06f
可以看出,是同一个dao
在bookdao中添加属性label,设置其值为1,并添加其getter和setter方法
@Repository
public class BookDao {
private String lable=“1”;
public String getLable() {
return lable;
}
public void setLable(String lable) {
this.lable = lable;
}
}
在配置类中使用@Bean的方式将dao注入到容器中,设置bookdao中的lable属性值为2:
@ComponentScan({“com.atguigu.service”,“com.atguigu.dao”,“com.atguigu.controller”})
@Component
@ComponentScan({“com.atguigu.service”,“com.atguigu.dao”,“com.atguigu.controller”})
public class MainConfigOfAutowired {
@Bean
public BookDao bookDao(){
BookDao bookDao=new BookDao();
bookDao.setLable(“2”);
return new BookDao();
}
}
在bookservice中通过自动装配获取Dao
@Service
public class BookService {
@Autowired
private BookDao bookDao;
public void print(){
System.out.println(bookDao);
}
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao +
'}';
}
}
在测试类中获取dao:
public void test01(){
BookService bookService=applicationContext.getBean(BookService.class);
System.out.println(bookService);
}
测试结果:BookService{bookDao=BookDao{lable=‘1’}}
测试结果分析:
此时容器中有两个dao组件,一个叫bookDao,一个叫bookDao2,由于@Autowired自动装配注解默认情况下优先按照类型去容器找对应的组件
因此此时的结果按照类型找到的dao组件
我们可以通过@qualifier注解指定要将哪个组件添加到容器中
@Qualifier(“bookDao2”)