浅谈@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 相关文章推荐
详解Java线程池是如何重复利用空闲线程的
Jun 26 Java/Android
Spring整合Mybatis的全过程
Jun 28 Java/Android
分析JVM源码之Thread.interrupt系统级别线程打断
Jun 29 Java/Android
分析ZooKeeper分布式锁的实现
Jun 30 Java/Android
Java使用httpRequest+Jsoup爬取红蓝球号码
Jul 02 Java/Android
Springboot配置suffix指定mvc视图的后缀方法
Jul 03 Java/Android
SpringBoot+Vue+JWT的前后端分离登录认证详细步骤
Sep 25 Java/Android
Android自定义ScrollView实现阻尼回弹
Apr 01 Java/Android
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
Apr 13 Java/Android
springboot+rabbitmq实现智能家居实例详解
Jul 23 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 操作文件的一些FAQ总结
2009/02/12 PHP
php中DOMElement操作xml文档实例演示
2013/03/26 PHP
ThinkPHP中url隐藏入口文件后接收alipay传值的方法
2014/12/09 PHP
php支持中文字符串分割的函数
2015/05/28 PHP
php+mysql实现简单的增删改查功能
2015/07/13 PHP
Yii框架响应组件用法实例分析
2019/09/04 PHP
javascript面向对象编程(一) 实例代码
2010/06/25 Javascript
到处都是jQuery选择器的年代 不了解它们的性能,行吗
2012/06/18 Javascript
js实现图片放大缩小功能后进行复杂排序的方法
2012/11/08 Javascript
jquery获取被勾选的checked(选中)的那一行的3列和4列的值
2013/07/04 Javascript
JavaScript实现LI列表数据绑定的方法
2015/08/04 Javascript
HTML5 js实现拖拉上传文件功能
2020/11/20 Javascript
JS实现移动端按首字母检索城市列表附源码下载
2017/07/05 Javascript
vue如何使用 Slot 分发内容实例详解
2017/09/05 Javascript
Vue仿支付宝支付功能
2018/05/25 Javascript
微信小程序模拟cookie的实现
2018/06/20 Javascript
NodeJs实现简单的爬虫功能案例分析
2018/12/05 NodeJs
JavaScript Array.flat()函数用法解析
2020/09/02 Javascript
vue的$http的get请求要加上params操作
2020/11/12 Javascript
javascript实现左右缓动动画函数
2020/11/25 Javascript
arcgis.js控制地图地体的显示范围超出区域自动弹回(实现思路)
2021/01/28 Javascript
python3读取MySQL-Front的MYSQL密码
2017/05/03 Python
python实现闹钟定时播放音乐功能
2018/01/25 Python
使用Python横向合并excel文件的实例
2018/12/11 Python
python 字典套字典或列表的示例
2019/12/16 Python
python使用梯度下降算法实现一个多线性回归
2020/03/24 Python
使用css3实现的tab选项卡代码分享
2014/12/09 HTML / CSS
html5 实现客户端验证上传文件的大小(简单实例)
2016/05/15 HTML / CSS
自荐信包含哪些内容
2013/10/30 职场文书
医院总经理职责
2013/12/26 职场文书
社区庆八一活动方案
2014/02/02 职场文书
人力资源部经理岗位职责规定
2014/02/23 职场文书
公司年会抽奖活动主持词
2014/03/31 职场文书
读鲁迅先生的经典名言
2019/08/20 职场文书
Java使用JMeter进行高并发测试
2021/11/23 Java/Android
如何解决flex文本溢出问题小结
2022/07/15 HTML / CSS