浅谈@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 相关文章推荐
Win10系统下配置Java环境变量
Jun 13 Java/Android
解决tk mapper 通用mapper的bug问题
Jun 16 Java/Android
新手初学Java List 接口
Jul 07 Java/Android
SpringRetry重试框架的具体使用
Jul 25 Java/Android
OpenCV实现普通阈值
Nov 17 Java/Android
MybatisPlus EntityWrapper如何自定义SQL
Mar 22 Java/Android
Java字符缓冲流BufferedWriter
Apr 09 Java/Android
Spring Data JPA框架自定义Repository接口
Apr 28 Java/Android
Java版 单机五子棋
May 04 Java/Android
Java 死锁解决方案
May 11 Java/Android
Spring中bean集合注入的方法详解
Jul 07 Java/Android
OpenFeign实现远程调用
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的header和asp中的redirect比较
2006/10/09 PHP
php 提速工具eAccelerator 配置参数详解
2010/05/16 PHP
Yii2框架BootStrap样式的深入理解
2016/11/07 PHP
php 开发中加密的几种方法总结
2017/03/22 PHP
firefox下jQuery UI Autocomplete 1.8.*中文输入修正方法
2012/09/19 Javascript
JS实现悬浮移动窗口(悬浮广告)的特效
2013/03/12 Javascript
使用JS 清空File控件的路径值
2013/07/08 Javascript
js函数获取html中className所在的内容并去除标签
2013/09/08 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
2014/01/23 Javascript
jQuery实现流动虚线框的方法
2015/01/29 Javascript
学习JavaScript鼠标响应事件
2015/12/25 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
2017/08/02 Javascript
vue登录路由验证的实现
2017/12/13 Javascript
可能被忽略的一些JavaScript数组方法细节
2019/02/28 Javascript
详解vue中使用axios对同一个接口连续请求导致返回数据混乱的问题
2019/11/06 Javascript
Ant Design Pro 下实现文件下载的实现代码
2019/12/03 Javascript
基于vue3.0.1beta搭建仿京东的电商H5项目
2020/05/06 Javascript
python实现括号匹配的思路详解
2018/08/23 Python
python tkinter界面居中显示的方法
2018/10/11 Python
详解Python locals()的陷阱
2019/03/26 Python
python 多维高斯分布数据生成方式
2019/12/09 Python
python tkinter 设置窗口大小不可缩放实例
2020/03/04 Python
Django框架models使用group by详解
2020/03/11 Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
2020/03/18 Python
python编写softmax函数、交叉熵函数实例
2020/06/11 Python
一款基于css3麻将筛子3D翻转特效的实例教程
2014/12/31 HTML / CSS
介绍一下Java的事务处理
2012/12/07 面试题
前台领班岗位职责
2013/12/04 职场文书
中式面点餐厅创业计划书
2014/01/29 职场文书
教师考察材料范文
2014/06/03 职场文书
工会趣味活动方案
2014/08/18 职场文书
2015年会计人员工作总结
2015/05/22 职场文书
2019交通安全宣传标语集锦!
2019/06/28 职场文书
《卧薪尝胆》读后感3篇
2019/12/26 职场文书
dubbo服务整合zipkin详解
2021/07/26 Java/Android
Python中的协程(Coroutine)操作模块(greenlet、gevent)
2022/05/30 Python