Spring注解开发之属性赋值和自动装配

属性赋值

@Value

bean定义

@Getter
@Setter
public class Person {
    // 使用@Value
    // 1. 基本数值
    // 2. 可以写SpEL:#{}
    // 3. 可以写${} 取出配置文件的值


    @Value("Lebron")
    private String name;
    @Value("#{23+5}")
    private int age;
}

配置类

@Configuration
public class MainConfigOfPropertyValues {

    @Bean
    public Person person(){
        return new Person();
    }

}

@PropertySource

配置类

@PropertySource(value = {"classpath:/person.properties"})
@Configuration
public class MainConfigOfPropertyValues {

    @Bean
    public Person person(){
        return new Person();
    }

}

bean定义

    @Value("Lebron")
    private String name;
    @Value("#{23+5}")
    private int age;

    @Value("${person.nickName}")
    private String nickname;

person.properties

person.nickName = king

自动装配

@Autowired

自动找到容器中的bean,优先根据id去找

    @Autowired
    BookDao bookDao2;
    
    优先会找bookDao2的bean
  • 构造器

    默认加载IOC容器中的组件,容器启动会调用无参构造器,再进行初始化赋值

  • 参数

  • 方法

    标注在方法上,spring容器创建当前对象,就会调用方法,完成赋值。方法实用的参数,自定义类型的值从IOC容器中获取。

  • 属性

  • 用@Bean标注的方法创建对象的时候,方法参数的值会从容器中获取。可以不用写@Autowired

都是从容器中获取组件。

@Qualifier

指定自动注入的bean组件id

    @Qualifier("bookDao")
    @Autowired
    BookDao bookDao2;
    
    只会去找id为bookDao的bean,没有则会报错

@Primary

优先加载某一类bean,即使有其他的id的bean,会优先primary的bean

@Repository
@Primary
public class BookDao {

    private String label = "1";

    public String getLabel() {
        return this.label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    @Override
    public String toString() {
        return "BookDao{" +
                "label='" + this.label + '\'' +
                '}';
    }
}

注意:优先级:@Qualifier > @Primary > @Autowired

@Resource

JSR250注解

类似于@Autowired,默认按照名称来装配,可以用name属性指定

Aware

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactroy),实现xxxAware,在创建对象的时候,会调用接口规定的方法注入相关组件。

xxxAware:功能使用xxxProcessor来实现的。

@Component
public class Red implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {
    private ApplicationContext applicationContext;

    @Override
    public void setBeanName(String s) {
        System.out.println("当前bean的名字" + s);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("当前容器"+applicationContext);
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
        String s = stringValueResolver.resolveStringValue("${os.name} #{20*12}");
        System.out.println("解析的字符串"+s);

    }
}

spring源码中:

postProcessBeforeInitialization
 if (!(bean instanceof EnvironmentAware)
 && !(bean instanceof EmbeddedValueResolverAware) 
 && !(bean instanceof ResourceLoaderAware) 
 && !(bean instanceof ApplicationEventPublisherAware) 
 && !(bean instanceof MessageSourceAware) 
 && !(bean instanceof ApplicationContextAware)) {...}
 

@Profile

spring可以根据当前环境,动态的激活和切换一系列组件的功能。

指定组件在那个环境的情况下,才能被注册到容器中。

@Profile("test")
@Bean("testDataSource")
public DataSource dataSource(){}

@Profile("dev")
@Bean("devDataSource")
public DataSource dataSource(){}

如上,加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。

如果写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能生效。

没有环境标识的bean,默认都是加载的。

  1. 使用命令行动态参数激活环境,在虚拟机参数位置加载 -Dspring.profiles.active=test
    1. 创建一个applicationContext
    2. 设置需要激活的环境applicationContext.getEnvironment().setActiveProfiles("test","dev")
    3. 注册住配置类applicationContext.register(MainConfigOfProfile.class)
    4. 启动刷新容器application.refresh()
posted @ 2020-09-20 22:35  Jimmyhe  阅读(223)  评论(0编辑  收藏  举报