Bean

ConfigurationProperties 接口

public @interface ConfigurationProperties {

    @AliasFor("prefix")
    String value() default "";

    @AliasFor("value")
    String prefix() default "";
}

在类名上加上 @ConfigurationProperties 注解,读取 application.properties 配置 Bean

@ConfigurationProperties("spring.datasource")
@Component
@Data
public class DataSourceBean {
    private String url;
    private String username;
    private String password;
}
spring.datasource.url=jdbc:mysql://localhost:3306/kangpan?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useAffectedRows=true
spring.datasource.username=root
spring.datasource.password=

启动项目 控制台打印 url

@Component
@Slf4j
public class TestRunner implements ApplicationRunner {

    @Autowired
    private DataSourceBean dataSourceBean;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info(dataSourceBean.getUrl());
}

配置 Bean 的属性

@RestController
@RequestMapping("/test")
@ConfigurationProperties(prefix = "spring.datasource")
@Slf4j
public class Test {
    private String username;
    public void setUsername(String username) {
        this.username = username;
    }
    @GetMapping(path = "/")
    public String test() {
        return username;
    }
}

浏览器输入 http://localhost:8081/test/ 打印了 root

@Component 配置 Bean@Repository @Service @Controller 等效),定义一个接口 Todo

public interface Todo {
    void print();
}

两个实现类 Foo Bar

@Slf4j
@Component
public class Foo implements Todo {
    @Override
    public void print() {
        log.info("foo");
    }
}
@Slf4j
@Component
public class Bar implements Todo {
    @Override
    public void print() {
        log.info("bar");
    }
}

@Autowired 根据类型注入,所有类型为 Todo 的全部注入 list ( 指 ForBar)
@Inject 也是按类型注入,不过没有 required 属性
@Qualifier 根据名称注入

@Component("todos")
@Data
public class Todos {
    @Autowired(required = false)
    private List<Todo> list;
}
@RestController
@RequestMapping("/test")
@Slf4j
public class Test {

    @Qualifier("todos")
    @Autowired
    private Todos todos;

    @GetMapping(path = "/")
    public String test() {
        todos.getList().stream().forEach( e -> e.print());
        return "";
    }
}

浏览器输入 http://localhost:8081/test/ 控制台打印 barfoo
如果 foo 要优先打印,在 Foo 类上加 @Order(value = 1),值越小优先级越高,Foo 优先加载

实现延迟加载 定义一个 LazyDo

@Lazy
@Service
@Slf4j
public class LazyDo {

    public void todo() {
        log.info("lazy todo");
    }
}

构造注入 lazyDao@Resource 默认按名称注入,匹配不上按类型

@RestController
@RequestMapping("/test")
@Slf4j
public class Test {

    private LazyDo lazyDo;

    @Lazy
    @Resource(name = "lazyDo")
    private void setLazyDo(LazyDo lazyDo) {
        this.lazyDo = lazyDo;
    }

    @GetMapping(path = "/")
    public String test() {
        lazyDo.todo();
        return "";
    }
}

启动项目 lazyDao 加载为 null

this.lazyDo = lazyDo; lazyDao: null lazyDo: "com.kangpan.model.lazy@7a65a360"

浏览器访问地址 http://localhost:8081/test/ 控制台打印 lazy todo

Bean 默认是单例,在类上加注解 @Scope("prototype") 多例

看下 Bean 初始化 及 销毁前 执行


@Service
@Slf4j
public class Todo {

    @PostConstruct
    public void init() {
        log.info("init");
    }

    @PreDestroy
    public void destroy() {
        log.info("destroy");
    }
}

运行项目 打印台输出 init ,关闭项目 打印台输出 destroy

根据当前环境配置 Bean

@Data
public class TestDev {
    private String name;
    public TestDev(String name) {
        this.name = name;
    }
}

application.properties 配置

test.name=testName // @Value 赋值
spring.profiles.active=dev // 当前环境

配置 devtest 环境下的 Bean

@Configuration
public class Dev {

    @Bean
    @Profile("dev")
    public TestDev testDev(@Value("${test.name}") String name) {
        return new TestDev(name);
    }

    @Bean
    @Profile("test")
    public TestDev testTest(@Value("${test.name}") String name) {
        return new TestDev(name);
    }
}
@RestController
@RequestMapping("/test")
public class Test {

    @Autowired
    private TestDev testDev;


    @GetMapping(path = "/")
    public String test() {
        return testDev.getName();
    }
}

浏览器输入 http://localhost:8081/test/ 打印 testName

XML 配置 Bean 简化

属性

<property name = "name",value = "value" />

构造参数

<constructor-arg type="java.lang.String" value="value" />
<constructor-arg ref="refBean" />

集合

<property name = "name">
  <map>
    <entry key="key" value="value">
  </map>
</property>

<property name = "name">
  <map>
    <entry key-ref="keyBean" value-ref="valueBean">
  </map>
</property>

引用

<property name="name" ref="refBean" />

或者 XML 声明 p 命名空间,然后配置 Bean ,特殊字符 用 <![CDATA[]]> 转义

项目启动 @SpringBootApplication 注解中的 @EnableAutoConfiguration 会加载配置文件的 Bean

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

@EnableAutoConfiguration
public @interface SpringBootApplication {
}

resources/META-INF/spring.factories 文件中配置

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.kangpan.model.Configs

Configs

@EnableConfigurationProperties
@Import({ConfigFoo.class,ConfigBar.class})
public class Configs {

}

引入的 ConfigFoo ConfigBar

@Slf4j
public class ConfigBar {
    public ConfigBar() {
        log.info("ConfigBar");
    }
}
@Slf4j
public class ConfigFoo {
    public ConfigFoo() {
        log.info("ConfigFoo");
    }
}

启动项目 控制台打印 ConfigBar ConfigFoo,如果 @EnableConfigurationProperties 改成 @Configuration 不需要在 resources/META-INF/spring.factories 文件中配置
看下 Configuration 接口,加了 @Component 注解 会实例化 Bean

@Component
public @interface Configuration {}

@ConfigurationProperties 结合 @EnableConfigurationProperties 配置Bean

@ConfigurationProperties("spring.datasource") // 读取  application.properties 中的配置
@Data
public class DataSourceBean2 {
    private String url;
    private String username;
    private String password;
}

application.properties 文件中配置

spring.datasource.url=jdbc:mysql://localhost:3306/kangpan?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useAffectedRows=true
spring.datasource.username=root
spring.datasource.password=

@EnableConfigurationProperties 使 @ConfigurationProperties 注解的类注入自身

@EnableConfigurationProperties(DataSourceBean2.class)
@Slf4j
public class DataSourceBeanConfig {

    private DataSourceBean2 dataSourceBean2;

    @Autowired
    public DataSourceBeanConfig(DataSourceBean2 dataSourceBean2) {
        this.dataSourceBean2 = dataSourceBean2;
        log.info("url: {}",dataSourceBean2.getUrl());
    }
}

spring.factories 配置 或者 DataSourceBeanConfig 类 加上 @Configuration 或者 @Component 注解

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.kangpan.model.DataSourceBeanConfig

控制台打印 url

自定义 XML 配置 Bean, 在 resource/bean.xml 配置 dataSourceBean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       ">
    <bean id="dataSourceBean" class="com.kangpan.model.DataSourceBean"> </bean>
</beans>

结合 @ConfigurationProperties 属性赋值

@ConfigurationProperties("spring.datasource")
@Data
public class DataSourceBean {
    private String url;
    private String username;
    private String password;
}

利用 @ImportResource 导入 bean.xml 配置的 Bean

@Component
@Slf4j
@ImportResource("classpath:bean.xml")
public class TestRunner implements ApplicationRunner {

    @Autowired
    private DataSourceBean dataSourceBean;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("dataSourceBean.getUrl():{}",dataSourceBean.getUrl());
}

项目启动 控制台打印 url

自定义 properties 配置 Bean,在 resources/dataSource.properties 配置

spring.datasource.url=jdbc:mysql://localhost:3306/kangpan?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useAffectedRows=true
spring.datasource.username=root
spring.datasource.password=

@PropertySource 加载指定文件的属性, @Value 赋值

@PropertySource("classpath:dataSource.properties")  
@Data
@Component
public class DataSourcesBean {
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
}

使用 @ConfigurationProperties 属性赋值

@PropertySource("classpath:dataSource.properties")
@Data
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourcesBean {
    private String url;
    private String username;
    private String password;
}
@Component
@Slf4j
public class TestRunner implements ApplicationRunner {

    @Autowired
    private DataSourcesBean dataSourcesBean;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("dataSourcesBean.getUrl():{}",dataSourcesBean.getUrl());
}

运行项目 打印 url

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容