浅谈@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中Map的遍历性能问题
Jun 26 Java/Android
新手初学Java网络编程
Jul 07 Java/Android
Spring实现内置监听器
Jul 09 Java/Android
idea以任意顺序debug多线程程序的具体用法
Aug 30 Java/Android
Spring中的使用@Async异步调用方法
Nov 01 Java/Android
Java 实现限流器处理Rest接口请求详解流程
Nov 02 Java/Android
SpringBoot+Redis实现布隆过滤器的示例代码
Mar 17 Java/Android
Java 超详细讲解IO操作字节流与字符流
Mar 25 Java/Android
Java 超详细讲解hashCode方法
Apr 07 Java/Android
Java处理延时任务的常用几种解决方案
Jun 01 Java/Android
使用Postman测试需要授权的接口问题
Jun 21 Java/Android
Java Redisson多策略注解限流
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
PHP GD 图像处理组件的常用函数总结
2010/04/28 PHP
php小技巧 把数组的键和值交换形成了新的数组,查找值取得键
2011/06/02 PHP
php之readdir函数用法实例
2014/11/13 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
删除PHP数组中头部、尾部、任意元素的实现代码
2017/04/10 PHP
PHP实现的AES加密、解密封装类与用法示例
2018/08/02 PHP
PHP pthreads v3下worker和pool的使用方法示例
2020/02/21 PHP
JS中剪贴板兼容性、判断复制成功或失败
2021/03/09 Javascript
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
JavaScript对象之间的转换 jQuery对象和原声DOM
2011/03/07 Javascript
js自动闭合html标签(自动补全html标记)
2012/10/04 Javascript
jquery下div 的resize事件示例代码
2014/03/09 Javascript
JavaScript使用HTML5的window.postMessage实现跨域通信例子
2014/04/11 Javascript
jquery的trigger和triggerHandler的区别示例介绍
2014/04/20 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
2014/05/14 Javascript
基于NodeJS的前后端分离的思考与实践(四)安全问题解决方案
2014/09/26 NodeJs
javascript进行四舍五入方法汇总
2014/12/16 Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
2016/02/26 Javascript
使用Vue实现移动端左滑删除效果附源码
2019/05/16 Javascript
vue-cli3.0实现一个多页面应用的历奇经历记录总结
2020/03/16 Javascript
[05:43]VG.R战队教练Mikasa专访:为目标从未停止战斗
2016/08/02 DOTA
正确理解python中的关键字“with”与上下文管理器
2017/04/21 Python
Python图片裁剪实例代码(如头像裁剪)
2017/06/21 Python
数据清洗--DataFrame中的空值处理方法
2018/07/03 Python
Python增强赋值和共享引用注意事项小结
2019/05/28 Python
Python 共享变量加锁、释放详解
2019/08/28 Python
Python2和Python3中@abstractmethod使用方法
2020/02/04 Python
python des,aes,rsa加解密的实现
2021/01/16 Python
CSS3中Color的一些特性介绍
2012/05/27 HTML / CSS
纯CSS3实现给头像加个光芒四射且旋转的背景动画效果
2014/05/07 HTML / CSS
浅析HTML5中的download属性使用
2019/03/13 HTML / CSS
TripAdvisor印尼站:全球领先的旅游网站
2018/03/15 全球购物
党的群众路线教育实践活动个人整改措施范文
2014/11/04 职场文书
2014年服务行业工作总结
2014/11/18 职场文书
学生安全责任协议书
2016/03/22 职场文书
python process模块的使用简介
2021/05/14 Python