浅谈@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生成License的实现示例
Jun 16 Java/Android
Java并发编程必备之Future机制
Jun 30 Java/Android
swagger如何返回map字段注释
Jul 03 Java/Android
spring cloud gateway中如何读取请求参数
Jul 15 Java/Android
idea以任意顺序debug多线程程序的具体用法
Aug 30 Java/Android
Java异常处理try catch的基本用法
Dec 06 Java/Android
关于@OnetoMany关系映射的排序问题,使用注解@OrderBy
Dec 06 Java/Android
mybatis源码解读之executor包语句处理功能
Feb 15 Java/Android
spring cloud eureka 服务启动失败的原因分析及解决方法
Mar 17 Java/Android
教你在 Java 中实现 Dijkstra 最短路算法的方法
Apr 08 Java/Android
Spring中bean集合注入的方法详解
Jul 07 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
如何在smarty中增加类似foreach的功能自动加载数据
2013/06/26 PHP
PHP中模拟处理HTTP PUT请求的例子
2014/07/22 PHP
php获取textarea的值并处理回车换行的方法
2014/10/20 PHP
Yii框架在页面输出执行sql语句以方便调试的实现方法
2014/12/24 PHP
Zend Framework框架实现类似Google搜索分页效果
2016/11/25 PHP
PHP字符串和十六进制如何实现互相转换
2020/07/16 PHP
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
Javascript 学习笔记 错误处理
2009/07/30 Javascript
javascript 函数及作用域总结介绍
2013/11/12 Javascript
jQuery实现冻结表头的方法
2015/03/09 Javascript
javascript基于DOM实现权限选择实例分析
2015/05/14 Javascript
freemarker判断对象是否为空的方法
2015/08/13 Javascript
将JavaScript的jQuery库中表单转化为JSON对象的方法
2015/11/17 Javascript
jquery遍历table的tr获取td的值实现方法
2016/05/19 Javascript
PHP捕捉异常中断的方法
2016/10/24 Javascript
JavaScript两种计时器的实例讲解
2019/01/31 Javascript
13 个npm 快速开发技巧(推荐)
2019/07/04 Javascript
原生js实现针对Dom节点的CRUD操作示例
2019/08/26 Javascript
vue resource发送请求的几种方式
2019/09/30 Javascript
如何在Vue中抽离接口配置文件
2019/10/31 Javascript
[02:20]DOTA2亚洲邀请赛 IG战队出场宣传片
2015/02/07 DOTA
Python实现的简单算术游戏实例
2015/05/26 Python
python如何去除字符串中不想要的字符
2020/07/05 Python
Python+selenium点击网页上指定坐标的实例
2019/07/05 Python
Django使用中间键实现csrf认证详解
2019/07/22 Python
python多进程下实现日志记录按时间分割
2019/07/22 Python
Python 动态导入对象,importlib.import_module()的使用方法
2019/08/28 Python
python实现低通滤波器代码
2020/02/26 Python
python如何输出反斜杠
2020/06/18 Python
python tkinter的消息框模块(messagebox,simpledialog)
2020/11/07 Python
CSS3 实现的火焰动画
2020/12/07 HTML / CSS
香港化妆品经销商:我的公主
2016/08/05 全球购物
初级软件工程师面试题 Junior Software Engineer Interview
2015/02/15 面试题
2019毕业典礼主持词!
2019/07/05 职场文书
go xorm框架的使用
2021/05/22 Golang
PHP面试题 wakeup魔法 Ezpop pop序列化与反序列化
2022/04/11 PHP