Spring 纯注解开发--004--配置文件获取值、自动装配

@PropertySource
  • 通过该标签读取外部配置文件中的k/v保存到运行的环境变量中;加载完外部配置文件以后可以使用${}取出配置文件中的值。
  • 代码
    • 配置类
    @Configuration
    @PropertySource({"classpath:/person.properties","classpath:/animal.properties"})
    public class BeanConfig {
    
    
        @Bean
        public Student student(){
            return new Student();
        }
    
        @Bean
        public MyPostProcess myPostProcess(){
            return new MyPostProcess();
        }
    }
    
    • 实体类
    @Getter
    public class Student {
    
    
        @Value("${person.name}")
        private String name;
        
    
        public Student(){
            System.out.println("student . . . constructor"+name);
        }
    
    
        @PostConstruct
        public void init(){
            System.out.println("student init...."+name);
        }
    }
    
    • 测试结果,可以看出在调用构造方法的时候,没有进行设置属性,在初始化方法之前将对象创建好,并且赋值好了,然后调用初始化方法在这里插入图片描述
自动装配
  • @Autowired

    • 默认优先按照类型去容器中找对应的组件:applicationContext.getBean(Person.class)
    • 如果找到多个相同类型的组件,再将属性(注入对象的地方)的名称,作为组件id去容器中查找。使用@Qualifier(“id名称”)来指定注入的对象是哪个ID(如果没有指定ID,则ID为类名,可以在@Bean进行ID的指定),而不是使用属性名。
    BookService{
    	//此时会去容器中找,id为bookDao1的BookDao
    	@Autowired
    	BookDao bookDao1;
    
    	@Autowired
    	//虽然属性名称是bookDao3,但是指定注入对象的ID为bookDao
    	@Qualifier("bookDao")
    	BookDao bookDao3;
    	
    }
    
    • 自动装配,默认一定要将属性赋值好,没有就会报错。可以使用@Qualifier(required=false)来设置,当没有对象注入时,也不会报错。此时组件为null。
  • @Primary,让spring进行自动装配时,默认使用首选的bean,也可以继续使用@Qualifier指定需要装配的bean。

    • @Primary用于生产Bean对象的地方,让spring看到哪个bean是优先装配的,修改默认装配的bean为@Primary修饰的bean。
    • @Qualifier用于注入Bean对象的地方,如果指定了就会根据ID值来进行装配,不会走默认首选装配的bean。
  • 应用

    • 实体类
    //设置id为mysql
    @Component("mysql")
    @Primary
    @ToString
    public class MySqlDataSourse extends BaseDataSourse {
    
        public MySqlDataSourse(){
            name = "mysql";
        }
    
        @Override
        public String toString() {
            return "MysqlDataSource["+name+"]";
        }
    }
    
    //设置id值为oracle
    @Component("oracle")
    public class OracleDataSource extends BaseDataSourse {
    
        public OracleDataSource(){
            name = "oracle Datasourse";
        }
    
        @Override
        public String toString() {
            return "OracleDataSource["+name+"]";
        }
    }
    
    • 测试类
    @Getter
    @ToString
    public class Student {
    
        @Autowired
        @Qualifier("oracle")
        private BaseDataSourse baseDataSourse;
    
    
        public Student(){
            System.out.println("student . . . constructor");
        }
    
    
        @PostConstruct
        public void init(){
            System.out.println("student init...."+baseDataSourse);
        }
    }
    
    • 情况:
      • 如果没有@Primary和@Qualifier注解,Student会报错,原因,是注入的是父类,存在两个子类,spring无法找到确切的信息,注入哪个。在这里插入图片描述
      • 在MysqlDataSourse上面添加上@Primary表明了,优先注入这个对象,所以,当只存在@Primary对象时,spring在注入时,会选择优先注入的对象。在这里插入图片描述
      • 当存在@Qualifier注解时,即表明了,需要注入具体id的对象,spring优先注入的对象即实效。如果通过id找不到对象,则会报错,也可以使用required=false来设置,可以注入为null。
        • 存在的情况
        • 在这里插入图片描述
        • 不存在的情况在这里插入图片描述
  • @Resource(JSR250规范)

    • 可以像@Autowired实现自动装配的功能,默认是按照组件名称进行自动装配的。
    • 缺点
      • 没有支持@Primary的功能
      • 没有支持@Autowired(required=false)的功能
  • @Inject(JSR330规范)

    • 需要导入javax.inject包,和Autowired功能一样,没有required=false的功能
  • 区别

    • @Autowired是spring框架的
    • 其他两个是Java规范的
@Autowired
  • 可以在构造器,参数,方法,属性进行标记
  • 【标注在方法上】:spring创建当前对象的时候,就会调用方法,完成赋值。方法使用的参数,自定义类型的值从IOC容器中进行获取。特别的,使用@Bean创建对象时,参数从容器中获取,而且默认不写@Autowired
//此处的car从容器中获取,可以在参数的位置添加注解@Autowired也可以不加,spring自动实现
@Bean
public Person person(Car car){
	return new Person(car);
}
  • 【标记在构造器上】:
    • spring中,默认加载IOC容器中的组件,容器启动会调用无参的构造器创建对象,再进行初始化赋值等操作
    • 当标在有参构造器上,spring加载时,会默认调用有参构造器,而且构造器要用的参数,会从容器中获取
    • 如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件从容器中获取
@Component
class Person{
	
	private Car car;
	
	//1. 此处可以在方法上加@Autowired
	//	@Autowired
	//2. 也可以在方法的参数上加
	//	public Person(@Autowired Car car)
	//3. 但是,因为只有一个有参构造器,所以可以省略,spring会自动寻找并注入
	public Person(Car car){
		this.car = car;
	}
}
  • 【标记在参数上】:从容器中获取对象,进行赋值等操作
注意:
	1. 标在构造器位置,如果组件只有一个有参构造器,如果这个有参构造器的Autowired可以省略,参数位置的组件还是可以从容器中获取
	2. 使用@Bean进行创建对象时,方法参数的值也是从容器中获取,而不用特别指定,当然也可以使用@Autowired注解,进行注入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值