浅谈@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 11 Java/Android
详解Java实践之建造者模式
Jun 18 Java/Android
详解Java实践之适配器模式
Jun 18 Java/Android
idea搭建可运行Servlet的Web项目
Jun 26 Java/Android
每日六道java新手入门面试题,通往自由的道路
Jun 30 Java/Android
Springboot配置suffix指定mvc视图的后缀方法
Jul 03 Java/Android
一篇文章带你学习Mybatis-Plus(新手入门)
Aug 02 Java/Android
Log4j.properties配置及其使用
Aug 02 Java/Android
java多态注意项小结
Oct 16 Java/Android
MyBatis配置文件解析与MyBatis实例演示
Apr 07 Java/Android
Ubuntu18.04下QT开发Android无法连接设备问题解决实现
Jun 01 Java/Android
Android 中的类文件和类加载器详情
Jun 05 Java/Android
SpringBoot2 参数管理实践之入参出参与校验的方式
Jun 16 #Java/Android
SpringBoot生成License的实现示例
Springboot如何使用logback实现多环境配置?
解决tk mapper 通用mapper的bug问题
一篇带你入门Java垃圾回收器
Java实现简易的分词器功能
Java用自带的Image IO给图片添加水印
You might like
Thinkphp+smarty+uploadify实现无刷新上传
2015/07/30 PHP
jquery ajax 检测用户注册时用户名是否存在
2009/11/03 Javascript
jQuery实现移动 和 渐变特效的点击事件
2015/02/26 Javascript
Java Mybatis框架入门基础教程
2015/09/21 Javascript
js判断一个字符串是以某个字符串开头的简单实例
2016/12/27 Javascript
jQuery中弹出iframe内嵌页面元素到父页面并全屏化的实例代码
2016/12/27 Javascript
jQuery ajax的功能实现方法详解
2017/01/06 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
Canvas + JavaScript 制作图片粒子效果
2017/02/08 Javascript
NodeJS实现微信公众号关注后自动回复功能
2017/05/31 NodeJs
Vue from-validate 表单验证的示例代码
2017/09/26 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
讲解vue-router之什么是嵌套路由
2018/05/28 Javascript
JS Ajax请求会话过期处理问题解决方法分析
2019/11/16 Javascript
vue element table中自定义一些input的验证操作
2020/07/18 Javascript
前端使用crypto.js进行加密的函数代码
2020/08/16 Javascript
vue 解决mintui弹窗弹起来,底部页面滚动bug问题
2020/11/12 Javascript
Node.js 中如何收集和解析命令行参数
2021/01/08 Javascript
[01:00:30]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第二场 10.31
2020/11/02 DOTA
将Django使用的数据库从MySQL迁移到PostgreSQL的教程
2015/04/11 Python
在Python中移动目录结构的方法
2016/01/31 Python
Python3 log10()函数简单用法
2019/02/19 Python
python-pyinstaller、打包后获取路径的实例
2019/06/10 Python
Python 字符串池化的前提
2020/07/03 Python
python如何对链表操作
2020/10/10 Python
俄罗斯香水和化妆品在线商店:Aroma-butik
2020/02/28 全球购物
恶意软件的定义
2014/11/12 面试题
Ajax主要包含了哪些技术
2014/06/12 面试题
骨干教师培训制度
2014/01/13 职场文书
2014年公司迎新年活动方案
2014/02/24 职场文书
投资建议书模板
2014/05/12 职场文书
本科毕业论文导师评语
2014/12/31 职场文书
2015年班主任德育工作总结
2015/05/21 职场文书
《蓝鲸的眼睛》读后感5篇
2020/01/15 职场文书
python实现网络五子棋
2021/04/11 Python
JavaScript实现简单计时器
2021/06/22 Javascript