浅谈@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 相关文章推荐
简单总结SpringMVC拦截器的使用方法
Jun 28 Java/Android
mybatis 解决从列名到属性名的自动映射失败问题
Jun 30 Java/Android
Java基础-封装和继承
Jul 02 Java/Android
Java日常练习题,每天进步一点点(38)
Jul 26 Java/Android
JAVA API 实用类 String详解
Oct 05 Java/Android
java项目构建Gradle的使用教程
Mar 24 Java/Android
Android Flutter实现图片滑动切换效果
Apr 07 Java/Android
java版 联机五子棋游戏
May 04 Java/Android
利用正则表达式匹配浮点型数据
May 30 Java/Android
java实现自定义时钟并实现走时功能
Jun 21 Java/Android
Android实现图片九宫格
Jun 28 Java/Android
Spring Boot实现文件上传下载
Aug 14 Java/Android
SpringBoot2 参数管理实践之入参出参与校验的方式
Jun 16 #Java/Android
SpringBoot生成License的实现示例
Springboot如何使用logback实现多环境配置?
解决tk mapper 通用mapper的bug问题
一篇带你入门Java垃圾回收器
Java实现简易的分词器功能
Java用自带的Image IO给图片添加水印
You might like
PHP与MySQL交互使用详解
2006/10/09 PHP
利用PHP生成静态HTML文档的原理
2012/10/29 PHP
深入PHP购物车模块功能分析(函数讲解,附源码)
2013/06/25 PHP
php fseek函数读取大文件两种方法
2016/10/12 PHP
js实现权限树的更新权限时的全选全消功能
2009/02/17 Javascript
jQuery自定义添加"$"与解决"$"冲突的方法
2015/01/19 Javascript
详解javascript跨浏览器事件处理程序
2016/03/27 Javascript
jQuery.form插件的使用及跨域异步上传文件
2016/04/27 Javascript
Javascript动画效果(1)
2016/10/11 Javascript
JS与jQuery实现子窗口获取父窗口元素值的方法
2017/04/17 jQuery
Angular中ng-repeat与ul li的多层嵌套重复问题
2017/07/24 Javascript
angular2+node.js express打包部署的实战
2017/07/27 Javascript
vue iview多张图片大图预览、缩放翻转
2019/07/13 Javascript
微信小程序实现左侧滑栏过程解析
2019/08/26 Javascript
解决layui的使用以及针对select、radio等表单组件不显示的问题
2019/09/05 Javascript
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
Python中计算三角函数之cos()方法的使用简介
2015/05/15 Python
Django中针对基于类的视图添加csrf_exempt实例代码
2018/02/11 Python
Python爬虫之网页图片抓取的方法
2018/07/16 Python
python同步windows和linux文件
2019/08/29 Python
pytorch 模型的train模式与eval模式实例
2020/02/20 Python
Ubuntu20下的Django安装的方法步骤
2021/01/24 Python
荷兰包包购物网站:The Little Green Bag
2018/03/17 全球购物
巴西服装和鞋子购物网站:Marisa
2018/10/25 全球购物
SneakerStudio英国:最佳运动鞋商店
2019/05/22 全球购物
描述一下JVM加载class文件的原理机制
2013/12/08 面试题
介绍一下SQL Server里面的索引视图
2016/07/31 面试题
大学生入党自我鉴定
2013/10/31 职场文书
护理职业生涯规划书
2014/01/24 职场文书
法律系毕业生自荐信范文
2014/03/27 职场文书
2014党委书记四风问题对照检查材料思想汇报
2014/09/22 职场文书
2015政治思想表现评语
2015/03/25 职场文书
商场收银员岗位职责
2015/04/07 职场文书
实习证明模板
2015/06/16 职场文书
2015年暑期实践报告范文
2015/07/13 职场文书
《勇者辞职不干了》上卷BD发售宣传CM公开
2022/04/08 日漫