问题描述
使用@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=李四)}
总结
以上为个人经验,希望能给大家一个参考,有什么理解不到位的地方,请大家多多指正,也希望大家多多支持脚本之家。