浅谈@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
新手入门Jvm-- JVM对象创建与内存分配机制
Jun 18 Java/Android
图解排序算法之希尔排序Java实现
Jun 26 Java/Android
Spring Data JPA的Audit功能审计数据库的变更
Jun 26 Java/Android
分析JVM源码之Thread.interrupt系统级别线程打断
Jun 29 Java/Android
Netty客户端接入流程NioSocketChannel创建解析
Mar 25 Java/Android
Java Spring Boot 正确读取配置文件中的属性的值
Apr 20 Java/Android
Java线程的6种状态与生命周期
May 11 Java/Android
SpringBoot使用AOP实现统计全局接口访问次数详解
Jun 16 Java/Android
SpringCloud超详细讲解Feign声明式服务调用
Jun 21 Java/Android
spring boot实现文件上传
Aug 14 Java/Android
Mybatis 一级缓存和二级缓存原理区别
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
咖啡的化学
2021/03/03 咖啡文化
PHP校验15位和18位身份证号的类封装
2018/11/07 PHP
让Firefox支持event对象实现代码
2009/11/07 Javascript
jQuery图片的展开和收缩实现代码
2013/04/16 Javascript
js innerHTML 改变div内容的方法
2013/08/03 Javascript
兼容主流浏览器的jQuery+CSS 实现遮罩层的简单代码
2014/10/14 Javascript
jQuery中:reset选择器用法实例
2015/01/04 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
AngularJS监听路由的变化示例代码
2016/09/23 Javascript
jQuery简单实现MD5加密的方法
2017/03/03 Javascript
详解nodeJS之二进制buffer对象
2017/06/03 NodeJs
GOJS+VUE实现流程图效果
2018/12/01 Javascript
js代码实现轮播图
2020/05/04 Javascript
JS实现密码框效果
2020/09/10 Javascript
[01:00]一分钟回顾2018DOTA2亚洲邀请赛现场活动
2018/04/07 DOTA
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
实例讲解python中的协程
2018/10/08 Python
解决Pycharm下面出现No R interpreter defined的问题
2018/10/29 Python
40个你可能不知道的Python技巧附代码
2020/01/29 Python
python有序查找算法 二分法实例解析
2020/02/18 Python
Pandas实现一列数据分隔为两列
2020/05/18 Python
python 合并多个excel中同名的sheet
2021/01/22 Python
css3动画效果抖动解决方法
2018/09/03 HTML / CSS
欧缇丽美国官网:Caudalie美国
2016/12/31 全球购物
澳大利亚最大的在线美发和美容零售商之一:My Hair Care & Beauty
2019/08/24 全球购物
中学生团员自我评价分享
2013/12/07 职场文书
班组长的岗位职责
2013/12/09 职场文书
违纪检讨书2000字
2014/02/08 职场文书
学校春季防火方案
2014/06/08 职场文书
法院干警四风问题个人对照检查材料思想汇报
2014/10/07 职场文书
大学生学期个人总结
2015/02/12 职场文书
个人总结与自我评价2015
2015/03/11 职场文书
Python实现GIF动图以及视频卡通化详解
2021/12/06 Python
SQL Server数据库基本概念、组成、常用对象与约束
2022/03/20 SQL Server
Python实现自动玩连连看的脚本分享
2022/04/04 Python