浅谈@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 相关文章推荐
Spring Data JPA使用JPQL与原生SQL进行查询的操作
Jun 15 Java/Android
java设计模式--建造者模式详解
Jul 21 Java/Android
SpringBoot整合RabbitMQ的5种模式实战
Aug 02 Java/Android
logback如何自定义日志存储
Aug 30 Java/Android
alibaba seata服务端具体实现
Feb 24 Java/Android
springboot layui hutool Excel导入的实现
Mar 31 Java/Android
详细介绍Java中的CyclicBarrier
Apr 13 Java/Android
Java实现添加条码或二维码到Word文档
Jun 01 Java/Android
Android开发手册自定义Switch开关按钮控件
Jun 10 Java/Android
springboot为异步任务规划自定义线程池的实现
Jun 14 Java/Android
SpringBoot详解整合Redis缓存方法
Jul 15 Java/Android
Springboot集成kafka高级应用实战分享
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 删除cookie和浏览器重定向
2009/03/16 PHP
PHP数组及条件,循环语句学习
2012/11/11 PHP
php牛逼的面试题分享
2013/01/18 PHP
php自定义排序uasort函数示例【二维数组按指定键值排序】
2019/06/19 PHP
在页面上点击任一链接时触发一个事件的代码
2007/04/07 Javascript
关于jquery动态增减控件的一些想法和小插件
2010/08/01 Javascript
使用javascript获取flash加载的百分比的实现代码
2011/05/25 Javascript
JavaScript极简入门教程(一):基础篇
2014/10/25 Javascript
JavaScript声明变量名的语法规则
2015/07/10 Javascript
详解基于Bootstrap扁平化的后台框架Ace
2015/11/27 Javascript
javascript实现随机显示星星特效
2016/01/28 Javascript
javascript html5移动端轻松实现文件上传
2020/03/27 Javascript
Bootstrap模态框(modal)垂直居中的实例代码
2016/08/18 Javascript
jquery实现输入框实时输入触发事件代码
2016/12/21 Javascript
详解webpack自动生成html页面
2017/06/29 Javascript
JS重学系列之聊聊new操作符
2019/03/04 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
基于vue.js仿淘宝收货地址并设置默认地址的案例分析
2020/08/20 Javascript
Python中函数的多种格式和使用实例及小技巧
2015/04/13 Python
黑科技 Python脚本帮你找出微信上删除你好友的人
2016/01/07 Python
Python 对象中的数据类型
2017/05/13 Python
Python分割指定页数的pdf文件方法
2018/10/26 Python
python解析命令行参数的三种方法详解
2019/11/29 Python
python实现的Iou与Giou代码
2020/01/18 Python
python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码
2021/01/06 Python
HTML5中的Web Notification桌面通知功能的实现方法
2019/07/29 HTML / CSS
中国电视购物:快乐购
2017/02/04 全球购物
高性能钓鱼服装:Huk Gear
2019/02/20 全球购物
团支书的期末学习总结自我评价
2013/11/01 职场文书
师范生的个人求职信范文
2014/01/04 职场文书
女子职高个人自荐书
2014/02/01 职场文书
《小儿垂钓》教学反思
2014/02/23 职场文书
交通事故协议书
2014/04/15 职场文书
行政答辩状范文
2015/05/21 职场文书
SpringMVC 整合SSM框架详解
2021/08/30 Java/Android
SONY600GR,国产收音机厂商永远的痛
2022/04/05 无线电