浅谈@Value和@Bean的执行顺序问题

问题描述

使用@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@Componentpublic 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 */@Repositorypublic 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@Componentpublic 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@Componentpublic 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@Componentpublic 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=李四)}

总结

以上为个人经验,希望能给大家一个参考,有什么理解不到位的地方,请大家多多指正,也希望大家多多支持。

你是自由的,不仅是身体上的自由,

浅谈@Value和@Bean的执行顺序问题

相关文章:

你感兴趣的文章:

标签云: