浅谈@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拦截器无法注入redisTemplate的解决方法
Jun 27 Java/Android
利用Java设置Word文本框中的文字旋转方向的实现方法
Jun 28 Java/Android
Spring Boot 整合 Apache Dubbo的示例代码
Jul 04 Java/Android
java设计模式--原型模式详解
Jul 21 Java/Android
JAVA API 实用类 String详解
Oct 05 Java/Android
maven依赖的version声明控制方式
Jan 18 Java/Android
Java实现二分搜索树的示例代码
Mar 17 Java/Android
MybatisPlus EntityWrapper如何自定义SQL
Mar 22 Java/Android
Java由浅入深通关抽象类与接口(上篇)
Apr 26 Java/Android
springboot读取resources下文件的方式详解
Jun 21 Java/Android
Java 多线程并发FutureTask
Jun 28 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/01 无线电
php开启安全模式后禁用的函数集合
2011/06/26 PHP
php set_time_limit()函数的使用详解
2013/06/05 PHP
table标签的结构与合并单元格的实现方法
2013/07/24 PHP
PHP+AJAX实现投票功能的方法
2015/09/28 PHP
PHP的Yii框架中View视图的使用进阶
2016/03/29 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
php的优点总结 php有哪些优点
2019/07/19 PHP
JavaScript内核之基本概念
2011/10/21 Javascript
离开当前页面前使用js判断条件提示是否要离开页面
2014/05/02 Javascript
使用CamanJS在Web页面上处理图像的技巧
2015/08/18 Javascript
通过XMLHttpRequest和jQuery实现ajax的几种方式
2015/08/28 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
JavaScript中常见内置函数用法示例
2018/05/14 Javascript
ES6 class类链式继承,实例化及react super(props)原理详解
2020/02/15 Javascript
[00:31]DOTA2上海特级锦标赛 Fnatic战队宣传片
2016/03/04 DOTA
[01:38:19]夜魇凡尔赛茶话会 第五期
2021/03/11 DOTA
给Python的Django框架下搭建的BLOG添加RSS功能的教程
2015/04/08 Python
python中MethodType方法介绍与使用示例
2017/08/03 Python
Django中如何防范CSRF跨站点请求伪造攻击的实现
2019/04/28 Python
Python 循环终止语句的三种方法小结
2019/06/24 Python
Python qqbot 实现qq机器人的示例代码
2019/07/11 Python
将tensorflow.Variable中的某些元素取出组成一个新的矩阵示例
2020/01/04 Python
Python3如何在服务器打印资产信息
2020/08/27 Python
Pytorch之Tensor和Numpy之间的转换的实现方法
2020/09/03 Python
深入解析HTML5中的Blob对象的使用
2015/09/08 HTML / CSS
GafasWorld西班牙:购买太阳镜、眼镜和隐形眼镜
2019/09/08 全球购物
广州一家公司的.NET面试题
2016/06/11 面试题
工程预算与管理应届生求职信
2013/10/06 职场文书
《可爱的动物》教学反思
2014/02/22 职场文书
外联部演讲稿
2014/05/24 职场文书
交通违章检讨书
2014/09/21 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
个人政治思想总结
2015/03/05 职场文书
抖音短视频(douyin)去水印工具的实现代码
2021/03/30 Javascript
pytorch 实现多个Dataloader同时训练
2021/05/29 Python