1. spring java config

版本:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>

@Configuration, @Bean

@Configuration替代了xml配置文件, 表明当前类是配置类
@Bean代替了bean标签, 表示想容器中注入对象, 被贴方法的返回值就是注入到容器中的对象, 方法名就是bean的id
代码:

@SpringBootApplication
public class Application
{
    public static void main(String[] args)
    {
        ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
        // 打印容器中bean的名字
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names)
        {
            System.out.println(name);
        }
    }
}
@Configuration(proxyBeanMethods = true)
public class BeanConfig
{
    @Bean
    public Person person()
    {
        Person p = new Person();
        return p;
    }
}
image.png

在@Configuration中proxyBeanMethods 默认就是为true的, 表示被@bean注解的方法的代理永远开启, 即使是通过代码直接调用; 这里的代理就是指返回从容器中获取的对象还是直接new
举个例子:

@SpringBootApplication
public class Application
{

    public static void main(String[] args)
    {
        ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
        BeanConfig config = ctx.getBean("beanConfig", BeanConfig.class);
        // 直接手动调用方法, 走不走代理?
        Person p1 = config.person();
        Person p2 = config.person();
        System.out.println(p1 == p2);
    }
}

当proxyBeanMethods为true时:
image.png

当proxyBeanMethods为false:
image.png

@Import

该注解的作用也是向容器中注入对象

@Data
public class Pet
{
    private String name;
    private Integer age;
}
//----------------------
@Import({Pet.class})
@Configuration(proxyBeanMethods = true)
public class BeanConfig
{
    @Bean
    public Person person()
    {
        Person p = new Person();
        return p;
    }
}
image.png

@ConditionalOnXXX

该系列注解表示在某种情况成立时, 才进行注入

@Import({Pet.class})
@Configuration(proxyBeanMethods = true)
public class BeanConfig
{
    // 当指定bean在容器中存在时
    @ConditionalOnBean(value = {Pet.class})
    @Bean
    public Person person()
    {
        Person p = new Person();
        return p;
    }
}
// ------------------------------------------
@SpringBootApplication
public class Application
{
    public static void main(String[] args)
    {
        ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
        Pet pet = ctx.getBean(Pet.class);
        System.out.println("pet被注入: " + (pet != null));
        Person p = ctx.getBean("person", Person.class);
        System.out.println("person被注入: " + (p != null));
    }
}
image.png

去掉Import注解之后, 我们可以看到在getBean时直接报错了, 所以是没有注入的:
image.png

@ImportResource

解决历史遗留问题, 如果项目中任然有xml配置bean的方式却又不想挨个迁移, 可以使用该注解直接导入配置文件: @ImportResource("classpath:beans.xml")

@ConfigurationProperties

该注解用于解析.yml/.properties中的配置并将值注入到相关的bean中, 需要配合@Component或是@EnableConfigurationProperties使用
yml:

pet:
  name: aa
  age: 5

用法1:

@Data
@Component
@ConfigurationProperties(prefix = "pet")
public class Pet
{
    private String name;
    private Integer age;
}

获取bean并打印:

image.png
用法2:

// 去掉component
@Data
@ConfigurationProperties(prefix = "pet")
public class Pet
{
    private String name;
    private Integer age;
}
// ----------------
@Configuration
// 开启Pet的配置绑定功能, 并将Pet注入到容器中
@EnableConfigurationProperties(value = {Pet.class})
public class BeanConfig
{
}

打印结果相同

推荐阅读更多精彩内容