记录一些注解。
@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工具类:
@Componentpublic class SpringContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextUtil.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext() {return applicationContext;}public static Object getBean(String name) {return getApplicationContext().getBean(name);}public static <T> T getBean(Class<T> clazz) {return getApplicationContext().getBean(clazz);}public static <T> T getBean(String name, Class<T> clazz) {return getApplicationContext().getBean(name, clazz);}}
Lite配置类:
@Configuration(proxyBeanMethods = true)public class LiteConfig {class Lite extends Object { }@Beanpublic Lite lite() {return new Lite();}}
Full配置类:
@Configuration(proxyBeanMethods = false)public class FullConfig {class Full extends Object { }@Beanpublic Full full() {return new Full();}}
测试类:
@SpringBootTestclass KHighnessApplicationTest {private final static Logger log = LoggerFactory.getLogger(KHighnessApplication.class);@Testpublic void fullMode() {FullConfig fullConfig = SpringContextUtil.getBean(FullConfig.class);Object obj1 = fullConfig.full();Object obj2 = fullConfig.full();log.info("Full模式下是否单例 => [{}]", obj1 == obj2);}@Testpublic void liteMode() {LiteConfig liteConfig = SpringContextUtil.getBean(LiteConfig.class);Object obj1 = liteConfig.lite();Object obj2 = liteConfig.lite();log.info("Lite模式下是否单例 => [{}]", obj1 == obj2);}}
liteMode测试结果:
Lite模式下是否单例 => [true]
fullMode测试结果:
Full模式下是否单例 => [false]
@PropertySource
功能
加载指定的配置文件到spring的environment中
- 与
@Value组合使用,将自定义属性文件中的属性变量注入到当前类的使用@Value标注的成员变量中 - 与
ConfugrationProperties组合使用,将文件与Java类绑定,将属性文件中的变量值注入到Java类的成员变量中
示例
在classpath下新建config文件夹,并新建highness.properties文件
highness.name=KHighnesshighness.age=19highness.birth=2001-09-11
新建配置类KhighnessConfig:
import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.PropertySource;import org.springframework.format.annotation.DateTimeFormat;import org.springframework.stereotype.Component;import java.util.Date;/*** @author KHighness* @since 2021-04-14*/@Component@PropertySource(value = {"config/highness.properties"})@ConfigurationProperties(prefix = "highness")public class KHighnessConfig {private String name;private Integer age;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birth;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;}public Date getBirth() {return birth;}public void setBirth(Date birth) {this.birth = birth;}@Overridepublic String toString() {return "KHighnessConfig[" +"name='" + name + '\'' +", age=" + age +", birth=" + birth +']';}}
新建命令行启动器OutputPropsRunner:
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;import top.parak.config.KHighnessConfig;/*** @author KHighness* @since 2021-04-14*/@Componentpublic class OutputPropsRunner implements CommandLineRunner {private static final Logger log = LoggerFactory.getLogger(OutputPropsRunner.class);@Autowiredprivate KHighnessConfig kHighnessConfig;@Overridepublic void run(String... args) throws Exception {log.info(kHighnessConfig.toString());}}
启动SpringBootApplication,可以看到有如下日志打印:
KHighnessConfig[name='KHighness', age=19, birth=Tue Sep 11 00:00:00 CST 2001]
