浅谈@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 相关文章推荐
解决Maven项目中 Invalid bound statement 无效的绑定问题
Jun 15 Java/Android
详解Java实现设计模式之责任链模式
Jun 23 Java/Android
关于springboot 配置date字段返回时间戳的问题
Jul 25 Java/Android
Java中try catch处理异常示例
Dec 06 Java/Android
SpringBoot2零基础到精通之数据库专项精讲
Mar 22 Java/Android
Java 数据结构七大排序使用分析
Apr 02 Java/Android
Android Rxjava3 使用场景详解
Apr 07 Java/Android
Java时间工具类Date的常用处理方法
May 25 Java/Android
Spring IOC容器Bean的作用域及生命周期实例
May 30 Java/Android
MyBatis XPathParser解析器使用范例详解
Jul 15 Java/Android
Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)
Jul 15 Java/Android
Java实现贪吃蛇游戏的示例代码
Sep 23 Java/Android
SpringBoot2 参数管理实践之入参出参与校验的方式
Jun 16 #Java/Android
SpringBoot生成License的实现示例
Springboot如何使用logback实现多环境配置?
解决tk mapper 通用mapper的bug问题
一篇带你入门Java垃圾回收器
Java实现简易的分词器功能
Java用自带的Image IO给图片添加水印
You might like
PHP初学者常见问题集合 修正版(21问答)
2010/03/23 PHP
jQuery+PHP+ajax实现微博加载更多内容列表功能
2014/06/27 PHP
javascript模仿msgbox提示效果代码
2008/06/10 Javascript
js监听表单value的修改同步问题,跨浏览器支持
2009/12/31 Javascript
javascript 使用 NodeList需要注意的问题
2013/03/04 Javascript
YUI模块开发原理详解
2013/11/18 Javascript
介绍一个简单的JavaScript类框架
2015/06/24 Javascript
JavaScript实现下拉列表框数据增加、删除、上下排序的方法
2015/08/11 Javascript
js文件中直接alert()中文出来的是乱码的解决方法
2016/11/01 Javascript
jQuery插件artDialog.js使用与关闭方法示例
2017/10/09 jQuery
nodejs操作mongodb的增删改查功能实例
2017/11/09 NodeJs
Node.js实现注册邮箱激活功能的方法示例
2018/03/23 Javascript
使用vue2实现购物车和地址选配功能
2018/03/29 Javascript
vue2.0实现音乐/视频播放进度条组件
2018/06/06 Javascript
ES6的解构赋值实例详解
2019/05/06 Javascript
layui 实现表单和文件上传一起传到后台的例子
2019/09/16 Javascript
解决layer 关闭当前弹窗 关闭遮罩层 input值获取不到的问题
2019/09/25 Javascript
微信小程序自定义菜单切换栏tabbar组件代码实例
2019/12/30 Javascript
零基础写python爬虫之urllib2使用指南
2014/11/05 Python
Python的迭代器和生成器
2015/07/29 Python
Python Web程序部署到Ubuntu服务器上的方法
2018/02/22 Python
Numpy 将二维图像矩阵转换为一维向量的方法
2018/06/05 Python
python地震数据可视化详解
2019/06/18 Python
在windows下使用python进行串口通讯的方法
2019/07/02 Python
Python使用Beautiful Soup爬取豆瓣音乐排行榜过程解析
2019/08/15 Python
Python帮你识破双11的套路
2019/11/11 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
详解CSS3中nth-child与nth-of-type的区别
2017/01/05 HTML / CSS
水果花束:Fruit Bouquets
2017/12/20 全球购物
荟萃全球保健品:维他购
2018/05/09 全球购物
创业计划书的写作技巧及要点
2014/01/31 职场文书
消防安全标语
2014/06/07 职场文书
政府个人对照检查材料思想汇报
2014/10/08 职场文书
2019年手机市场的调研报告2篇
2019/10/10 职场文书
PHP 技巧 * SVG 保存为图片(分享图生成)
2021/04/02 PHP
CentOS下安装Jenkins的完整步骤
2022/04/07 Servers