浅谈@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 16 Java/Android
新手入门Jvm-- JVM对象创建与内存分配机制
Jun 18 Java/Android
浅谈Python魔法方法
Jun 28 Java/Android
elasticSearch-api的具体操作步骤讲解
Jun 28 Java/Android
spring cloud gateway中如何读取请求参数
Jul 15 Java/Android
java多态注意项小结
Oct 16 Java/Android
Java实现二分搜索树的示例代码
Mar 17 Java/Android
Netty客户端接入流程NioSocketChannel创建解析
Mar 25 Java/Android
Android自定义ScrollView实现阻尼回弹
Apr 01 Java/Android
Java GUI编程菜单组件实例详解
Apr 07 Java/Android
springboot集成redis存对象乱码的问题及解决
Jun 16 Java/Android
JDK8中String的intern()方法实例详细解读
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 数据结构 算法描述 冒泡排序 bubble sort
2011/07/10 PHP
PHP通过串口实现发送短信
2015/07/08 PHP
Yii隐藏URL中index.php的方法
2016/07/12 PHP
php 多继承的几种常见实现方法示例
2019/11/18 PHP
jQuery对象和DOM对象相互转化
2009/04/24 Javascript
使用dynatrace-ajax跟踪JavaScript的性能
2010/04/12 Javascript
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
JQuery 控制内容长度超出规定长度显示省略号
2014/05/23 Javascript
使用javascript实现简单的选项卡切换
2015/01/09 Javascript
nodejs批量修改文件编码格式
2015/01/22 NodeJs
JavaScript中的replace()方法使用详解
2015/06/06 Javascript
关于Function中的bind()示例详解
2016/12/02 Javascript
轻松实现jQuery添加删除按钮Click事件
2017/03/13 Javascript
JavaScript模拟实现封装的三种方式及写法区别
2017/10/27 Javascript
AngularJS实现与后台服务器进行交互的示例讲解
2018/08/13 Javascript
在webstorm开发微信小程序之使用阿里自定义字体图标的方法
2018/11/15 Javascript
详解微信小程序-扫一扫 wx.scanCode() 扫码大变身
2019/04/30 Javascript
浅谈Vue3.0之前你必须知道的TypeScript实战技巧
2019/09/11 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
2019/11/13 Javascript
JavaScript实现留言板案例
2020/03/17 Javascript
记录一次websocket封装的过程
2020/11/23 Javascript
Python编程对列表中字典元素进行排序的方法详解
2017/05/26 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
python xpath获取页面注释的方法
2019/01/14 Python
Django+Xadmin构建项目的方法步骤
2019/03/06 Python
python配置文件写入过程详解
2019/10/19 Python
python中的数组赋值与拷贝的区别详解
2019/11/26 Python
selenium切换标签页解决get超时问题的完整代码
2020/08/30 Python
教师年终个人自我评价
2013/10/04 职场文书
热能动力工程毕业生自荐信
2013/11/07 职场文书
农村婚礼主持词
2014/03/13 职场文书
法人任命书范本
2014/06/04 职场文书
读群众路线的心得体会
2014/09/03 职场文书
2017年寒假社区服务活动总结
2016/04/06 职场文书
“鬼灭之刃”热度不减,其成功背后的原因是什么?
2022/03/22 日漫
利用For循环遍历Python字典的三种方法实例
2022/03/25 Python