浅谈@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 相关文章推荐
Win10系统下配置Java环境变量
Jun 13 Java/Android
启动Tomcat时出现大量乱码的解决方法
Jun 21 Java/Android
idea以任意顺序debug多线程程序的具体用法
Aug 30 Java/Android
Java tomcat手动配置servlet详解
Nov 27 Java/Android
正则表达式拆分url实例代码
Feb 24 Java/Android
Java 超详细讲解设计模式之中的抽象工厂模式
Mar 25 Java/Android
Java 写一个简单的图书管理系统
Apr 26 Java/Android
Java中生成微信小程序太阳码的实现方案
Jun 01 Java/Android
详解Spring Bean的配置方式与实例化
Jun 10 Java/Android
Springboot中如何自动转JSON输出
Jun 16 Java/Android
Java Spring Boot请求方式与请求映射过程分析
Jun 25 Java/Android
Spring boot admin 服务监控利器详解
Aug 05 Java/Android
SpringBoot2 参数管理实践之入参出参与校验的方式
Jun 16 #Java/Android
SpringBoot生成License的实现示例
Springboot如何使用logback实现多环境配置?
解决tk mapper 通用mapper的bug问题
一篇带你入门Java垃圾回收器
Java实现简易的分词器功能
Java用自带的Image IO给图片添加水印
You might like
推荐php模板技术[转]
2007/01/04 PHP
Smarty模板快速入门
2007/01/04 PHP
Wordpress php 分页代码
2009/10/21 PHP
学习php分页代码实例
2013/10/24 PHP
PHP读取Excel类文件
2017/05/15 PHP
Laravel中的chunk组块结果集处理与注意问题
2018/08/15 PHP
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
2010/09/14 Javascript
jQuery之日期选择器的深入解析
2013/06/19 Javascript
Table冻结表头示例代码
2013/08/20 Javascript
js 控制图片大小核心讲解
2013/10/09 Javascript
js获取url参数代码实例分享(JS操作URL)
2013/12/13 Javascript
jquery库或JS文件在eclipse下报错问题解决方法
2014/04/17 Javascript
JavaScript中遍历对象的property的3种方法介绍
2014/12/30 Javascript
jQuery中parentsUntil()方法用法实例
2015/01/07 Javascript
js实现Select列表各项上移和下移的方法
2015/08/14 Javascript
JavaScript实现斗地主游戏的思路
2016/02/29 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
JavaScrip数组删除特定元素的几种方法总结
2017/09/06 Javascript
vue 中的keep-alive实例代码
2018/07/20 Javascript
怎样使你的 JavaScript 代码简单易读(推荐)
2019/04/16 Javascript
vue路由传参三种基本方式详解
2019/12/09 Javascript
vue-cli单页面预渲染seo-prerender-spa-plugin操作
2020/08/10 Javascript
Python编程入门之Hello World的三种实现方式
2015/11/13 Python
Python IDLE入门简介
2017/12/08 Python
tensorflow 获取模型所有参数总和数量的方法
2018/06/14 Python
10个Python小技巧你值得拥有
2018/09/29 Python
python用pandas数据加载、存储与文件格式的实例
2018/12/07 Python
使用python对多个txt文件中的数据进行筛选的方法
2019/07/10 Python
Python3开发实例之非关系型图数据库Neo4j安装方法及Python3连接操作Neo4j方法实例
2020/03/18 Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
2021/02/03 Python
意大利制造的西装、衬衫和针对男士量身定制的服装:Lanieri
2018/04/08 全球购物
应届毕业生个人求职自荐信
2014/01/06 职场文书
开业庆典策划方案
2014/02/18 职场文书
党的群众路线教育实践活动动员会主持词
2014/03/20 职场文书
小学生作文评语大全
2014/04/21 职场文书
师德先进个人事迹材料
2014/12/19 职场文书