浅谈@Value和@Bean的执行顺序问题


Posted in Java/Android onJune 16, 2021

问题描述

使用@Autowired处理多个同种类型的bean,出现@Value和@Bean的执行顺序问题。

首先使用扫描包+注解的方式注册User类型的不同bean,分别是user、user1,注册方式如下

package com.fanyinhang.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * @author fanyinhang
 * @version 1.0
 * @create 2019/10/8-19:11
 */
@NoArgsConstructor
@Data
@AllArgsConstructor
@Component
public class User {
    private Integer id;
    private String name;
}

该方式得到User类型的名为user的bean

package com.fanyinhang.config;
import com.fanyinhang.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value={"com.fanyinhang.dao"})
public class AnnotationConfig {
    @Bean()
    public User user1(){
        return new User(2,"李四");
    }
}

UserDao配置如下:

package com.fanyinhang.dao;
import com.fanyinhang.bean.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 * @author fanyinhang
 * @version 1.0
 * @create 2019/10/8-19:17
 */
@Repository
public class UserDao {
    @Autowired()
    private User user1;
    
    @Override
    public String toString() {
        return "UserDao{" +
                "user1=" + user1 +
                '}';
    }
}
import com.fanyinhang.config.AnnotationConfig;
import com.fanyinhang.dao.UserDao;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * @author fanyinhang
 * @version 1.0
 * @create 2019/10/8-19:18
 */
public class Test3 {
    @Test
    public void testAutowired(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationConfig.class);
        UserDao userDao = context.getBean(UserDao.class);
        System.out.println(userDao);
    }
}

输出结果如下:

UserDao{user1=User(id=2, name=李四)}

没有加入@Value注解时是没有问题的,但是加入了@Value之后

package com.fanyinhang.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * @author fanyinhang
 * @version 1.0
 * @create 2019/10/8-19:11
 */
@NoArgsConstructor
@Data
@AllArgsConstructor
@Component
public class User {
    @Value("1")
    private Integer id;
    @Value("张三")
    private String name;
}

再次运行testWired方法后

结果输出如下:

UserDao{user1=User(id=1, name=张三)}

为什么会出现这种情况?

一开始,怎么也想不通,查看网上的资料大多数是说@Bean和@Value有执行顺序这一说法。

为了验证这一说法,做个对比试验

去掉了一个@Value(“张三”)

package com.fanyinhang.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * @author fanyinhang
 * @version 1.0
 * @create 2019/10/8-19:11
 */
@NoArgsConstructor
@Data
@AllArgsConstructor
@Component
public class User {
    @Value("1")
    private Integer id;
    //@Value("张三")
    private String name;
}

结果输出如下:

UserDao{user1=User(id=1, name=李四)}

问题原因

@Value和@Bean在不同文件下时,@Bean比@Value先执行。这样就回导致@Bean注入的值失效。

解决办法

网上说@Value和@Bean在不同文件下时,@Value比@Bean先执行,因此,我做了如下设置

把User.java下的@Value注解去掉,而是将@Value注解放在@bean同一文件下

package com.fanyinhang.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
/**
 * @author fanyinhang
 * @version 1.0
 * @create 2019/10/8-19:11
 */
@NoArgsConstructor
@Data
@AllArgsConstructor
@Component
public class User {
    private Integer id;
    private String name;
}
package com.fanyinhang.config;
import com.fanyinhang.bean.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value={"com.fanyinhang.dao"})
public class AnnotationConfig {
    @Bean()
    public User user1(@Value("1") Integer id,@Value("张三") String name){
        return new User(2,"李四");
    }
}

此时再运行测试方式,输出结果如下:

UserDao{user1=User(id=2, name=李四)}

总结

以上为个人经验,希望能给大家一个参考,有什么理解不到位的地方,请大家多多指正,也希望大家多多支持三水点靠木。

Java/Android 相关文章推荐
Springboot如何使用logback实现多环境配置?
Jun 16 Java/Android
Java数据结构之链表相关知识总结
Jun 18 Java/Android
SpringAop日志找不到方法的处理
Jun 21 Java/Android
springboot如何初始化执行sql语句
Jun 22 Java/Android
ObjectMapper 如何忽略字段大小写
Jun 29 Java/Android
浅谈resultMap的用法及关联结果集映射
Jun 30 Java/Android
Java面试题冲刺第十九天--数据库(4)
Aug 07 Java/Android
Spring Cloud 中@FeignClient注解中的contextId属性详解
Sep 25 Java/Android
SpringCloud之@FeignClient()注解的使用方式
Sep 25 Java/Android
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
Apr 13 Java/Android
Java后端 Dubbo retries 超时重试机制的解决方案
Apr 14 Java/Android
解决spring.thymeleaf.cache=false不起作用的问题
Jun 10 Java/Android
SpringBoot2 参数管理实践之入参出参与校验的方式
Jun 16 #Java/Android
SpringBoot生成License的实现示例
Springboot如何使用logback实现多环境配置?
解决tk mapper 通用mapper的bug问题
一篇带你入门Java垃圾回收器
Java实现简易的分词器功能
Java用自带的Image IO给图片添加水印
You might like
php短域名转换为实际域名函数
2011/01/17 PHP
destoon实现VIP排名一直在前面排序的方法
2014/08/21 PHP
PHP进阶学习之反射基本概念与用法分析
2019/06/18 PHP
javascript 带有滚动条的表格,标题固定,带排序功能.
2009/11/13 Javascript
老鱼 浅谈javascript面向对象编程
2010/03/04 Javascript
javascript 实现 秒杀,团购 倒计时展示的记录 分享
2013/07/12 Javascript
纯js分页代码(简洁实用)
2013/11/05 Javascript
JavaScript将Web页面内容导出到Word及Excel的方法
2015/02/13 Javascript
Js获取当前日期时间及格式化代码
2016/09/17 Javascript
js编写选项卡效果
2017/05/23 Javascript
vue router2.0二级路由的简单使用
2017/07/05 Javascript
在 Node.js 中使用 async 函数的方法
2017/11/17 Javascript
NodeJS简单实现WebSocket功能示例
2018/02/10 NodeJs
微信小程序bindinput与bindsubmit的区别实例分析
2019/04/17 Javascript
小程序绑定用户方案优化小结
2019/05/15 Javascript
原生JS实现天气预报
2020/06/16 Javascript
解决vue2中使用elementUi打包报错的问题
2020/09/22 Javascript
[01:46]辉夜杯—打造中国DOTA新格局
2015/12/25 DOTA
ubuntu系统下使用pm2设置nodejs开机自启动的方法
2018/05/12 NodeJs
用Cython加速Python到“起飞”(推荐)
2019/08/01 Python
pycharm导入源码的具体步骤
2020/08/04 Python
python爬虫---requests库的用法详解
2020/09/28 Python
Flask中jinja2的继承实现方法及实例
2021/03/03 Python
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
2013/01/09 HTML / CSS
英国版MAC彩妆品牌:Illamasqua
2018/04/18 全球购物
Lookfantastic意大利官网:英国知名美妆购物网站
2019/05/31 全球购物
阿里巴巴美国:Alibaba美国
2019/11/24 全球购物
美国最大的购物网站:Amazon.com(亚马逊美国)
2020/05/23 全球购物
网友共享的几个面试题关于Java和Unix等方面的
2016/09/08 面试题
大学运动会通讯稿
2014/01/28 职场文书
大学中国梦演讲稿
2014/04/23 职场文书
司法局2014法制宣传日活动总结
2014/11/01 职场文书
员工2014年度工作总结
2014/12/09 职场文书
特岗教师个人总结
2015/02/10 职场文书
奖金申请报告模板
2015/05/15 职场文书
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android