记录一些注解。

@Configuration

要点
(1)使用@Configuration标注的类是配置类,其本身也是组件,因为它本身就被@Component标注。
(2)配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的。
(3)proxyBeansMethods:代理bean的方法,默认是true。

模式

  • Full: @Configuration(_proxyBeanMethods = true)_
  • Lite: @Configuration(_proxyBeanMethods = false)_

在Full模式下,SpringBoot容器中再也不会保留配置类的代理对象,
在外面无限次调用组件都会产生新的对象,用于解决组件依赖。
在Lite模式下,SpringBoot总会检查配置类的成员组件是否在容器中,
如果在则直接使用容器中的组件,保持组件单实例,耗费性能。

场景
Full模式:配置类组件之间有依赖关系,方法会被调用得到之前单实例组件。
Lite模式:配置类组件之间无依赖关系,加速容器启动过程,减少判断。

示例
获取bean工具类:

  1. @Component
  2. public class SpringContextUtil implements ApplicationContextAware {
  3. private static ApplicationContext applicationContext;
  4. @Override
  5. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  6. SpringContextUtil.applicationContext = applicationContext;
  7. }
  8. public static ApplicationContext getApplicationContext() {
  9. return applicationContext;
  10. }
  11. public static Object getBean(String name) {
  12. return getApplicationContext().getBean(name);
  13. }
  14. public static <T> T getBean(Class<T> clazz) {
  15. return getApplicationContext().getBean(clazz);
  16. }
  17. public static <T> T getBean(String name, Class<T> clazz) {
  18. return getApplicationContext().getBean(name, clazz);
  19. }
  20. }

Lite配置类:

  1. @Configuration(proxyBeanMethods = true)
  2. public class LiteConfig {
  3. class Lite extends Object { }
  4. @Bean
  5. public Lite lite() {
  6. return new Lite();
  7. }
  8. }

Full配置类:

  1. @Configuration(proxyBeanMethods = false)
  2. public class FullConfig {
  3. class Full extends Object { }
  4. @Bean
  5. public Full full() {
  6. return new Full();
  7. }
  8. }

测试类:

  1. @SpringBootTest
  2. class KHighnessApplicationTest {
  3. private final static Logger log = LoggerFactory.getLogger(KHighnessApplication.class);
  4. @Test
  5. public void fullMode() {
  6. FullConfig fullConfig = SpringContextUtil.getBean(FullConfig.class);
  7. Object obj1 = fullConfig.full();
  8. Object obj2 = fullConfig.full();
  9. log.info("Full模式下是否单例 => [{}]", obj1 == obj2);
  10. }
  11. @Test
  12. public void liteMode() {
  13. LiteConfig liteConfig = SpringContextUtil.getBean(LiteConfig.class);
  14. Object obj1 = liteConfig.lite();
  15. Object obj2 = liteConfig.lite();
  16. log.info("Lite模式下是否单例 => [{}]", obj1 == obj2);
  17. }
  18. }

liteMode测试结果:

  1. Lite模式下是否单例 => [true]

fullMode测试结果:

  1. Full模式下是否单例 => [false]

@PropertySource

功能
加载指定的配置文件到spring的environment中

  • @Value组合使用,将自定义属性文件中的属性变量注入到当前类的使用@Value标注的成员变量中
  • ConfugrationProperties组合使用,将文件与Java类绑定,将属性文件中的变量值注入到Java类的成员变量中

示例
在classpath下新建config文件夹,并新建highness.properties文件

  1. highness.name=KHighness
  2. highness.age=19
  3. highness.birth=2001-09-11

新建配置类KhighnessConfig:

  1. import org.springframework.boot.context.properties.ConfigurationProperties;
  2. import org.springframework.context.annotation.PropertySource;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Component;
  5. import java.util.Date;
  6. /**
  7. * @author KHighness
  8. * @since 2021-04-14
  9. */
  10. @Component
  11. @PropertySource(value = {"config/highness.properties"})
  12. @ConfigurationProperties(prefix = "highness")
  13. public class KHighnessConfig {
  14. private String name;
  15. private Integer age;
  16. @DateTimeFormat(pattern = "yyyy-MM-dd")
  17. private Date birth;
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public Integer getAge() {
  25. return age;
  26. }
  27. public void setAge(Integer age) {
  28. this.age = age;
  29. }
  30. public Date getBirth() {
  31. return birth;
  32. }
  33. public void setBirth(Date birth) {
  34. this.birth = birth;
  35. }
  36. @Override
  37. public String toString() {
  38. return "KHighnessConfig[" +
  39. "name='" + name + '\'' +
  40. ", age=" + age +
  41. ", birth=" + birth +
  42. ']';
  43. }
  44. }

新建命令行启动器OutputPropsRunner:

  1. import org.slf4j.Logger;
  2. import org.slf4j.LoggerFactory;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.CommandLineRunner;
  5. import org.springframework.stereotype.Component;
  6. import top.parak.config.KHighnessConfig;
  7. /**
  8. * @author KHighness
  9. * @since 2021-04-14
  10. */
  11. @Component
  12. public class OutputPropsRunner implements CommandLineRunner {
  13. private static final Logger log = LoggerFactory.getLogger(OutputPropsRunner.class);
  14. @Autowired
  15. private KHighnessConfig kHighnessConfig;
  16. @Override
  17. public void run(String... args) throws Exception {
  18. log.info(kHighnessConfig.toString());
  19. }
  20. }

启动SpringBootApplication,可以看到有如下日志打印:

  1. KHighnessConfig[name='KHighness', age=19, birth=Tue Sep 11 00:00:00 CST 2001]