SpringBoot.02.SpringBoot创建对象与属性注入

x33g5p2x  于2022-04-11 转载在 Spring  
字(10.7k)|赞(0)|评价(0)|浏览(470)

SpringBoot创建对象与属性注入

前言

所谓SpringBoot创建对象就是将对象交给Spring来管理。在SpringBoot中我们可以使用注解。比如我们常用的@Component@Controller@Service@Repository等。不过这种方式一次只能创建一个对象;此外我们还可以使用@Configuration + @Bean的方式一次性创建多个对象。

属性注入是指我们可以将在配置文件中配置的信息注入到java文件中来使用。这样的使用场景在实际开发中是普遍存在的。比如我们要集成高德定位需要用到搞的提供的secret,这个值不能直接写死在代码中而只能写在配置文件中。而实际使用是在java中,这就需要我们将该属性值从配置文件注入到当前的java文件中。有关属性注入分为基本属性注入对象注入

下面我们以springboot-02-initializr项目为例来演示在SpringBoot创建对象与属性注入。

创建对象

单个对象的创建

​ 在springboot中可以管理单个对象可以直接使用spring框架中注解形式创建。常用的注解如下:

  • @Component: 通用的对象创建注解
  • @Controller :用来创建控制器对象
  • @Service :用来创建业务层对象
  • @Repository:用来创建DAO层对象
    原理上以上四个注解可以互相替代,@Component注解修饰了下面3个注解。在Spring中为了区分MVC各层,不建议这几个注解混用
1.TestController.java
  1. import com.christy.service.TestService;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. /**
  9. * @Author Christy
  10. * @Date 2021/9/1 11:06
  11. **/
  12. @RestController
  13. @RequestMapping("test")
  14. public class TestController {
  15. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  16. @Value("${server.port}")
  17. private Integer port;
  18. /**
  19. * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式
  20. */
  21. /*@Autowired
  22. private TestService testService;*/
  23. private TestService testService;
  24. @Autowired
  25. public TestController(TestService testService){
  26. this.testService = testService;
  27. }
  28. @RequestMapping("hello")
  29. public String sayHello(){
  30. log.info(testService.sayHello());
  31. return testService.sayHello() + "current port is " + port;
  32. }
  33. }
2.TestService
  1. /**
  2. * @Author Christy
  3. * @Date 2021/9/1 14:25
  4. **/
  5. public interface TestService {
  6. String sayHello();
  7. }
  8. import com.christy.service.TestService;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import org.springframework.stereotype.Service;
  12. /**
  13. * @Author Christy
  14. * @Date 2021/9/1 14:26
  15. * @Service 该注解标识当前对象为一个业务处理对象,并将当前对象交由Spring管理,默认在Spring工厂的名字是类名首字母小写
  16. **/
  17. @Service
  18. public class TestServiceImpl implements TestService {
  19. private static final Logger log = LoggerFactory.getLogger(TestServiceImpl.class);
  20. @Override
  21. public String sayHello() {
  22. log.info("Hello SpringBoot!");
  23. return "Hello SpringBoot!";
  24. }
  25. }
3.测试

启动项目,在浏览器中访问http://localhost:8802/test/hello,结果如下图所示:

由结果我们可以看到TestService在Spring中成功创建,并且在TestController中成功注入了。

多个对象的创建

​ 如何在springboot中像spring框架一样通过xml创建多个对象?SpringBoot也提供了如**@Configuration + @Bean**注解进行创建

  • @Configuration :代表这是一个spring的配置类,相当于Spring.xml配置文件
  • @Bean :用来在工厂中创建这个@Bean注解标识的对象
    @Bean将标识方法的返回值交由Spring工厂管理,在Spring中创建该对象。一般情况下我们将该方法名命名为返回值首字母小写
1.BeansConfig.java
  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import java.util.Calendar;
  4. /**
  5. * @Author Christy
  6. * @Date 2021/9/1 14:57
  7. *
  8. * @Configuration 标注在类上,作用:配置Spring容器(应用上下文),被它修饰的类表示可以使用Spring IoC容器作为bean定义的来源。
  9. * 相当于把该类作为Spring的xml配置文件中的<beans>元素(并且包含命名空间)
  10. * 简单的理解,被该注解标识的类就相当于SSM框架中的Spring.xml
  11. * @Bean 标注在方法上,作用:注册bean对象,被标记的方法的返回值会作为bean被加入到Spring IoC容器之中,bean的名称默认为方法名。
  12. * 相当于把该方法的返回值作为 xml 配置文件中<beans>的子标签<bean>
  13. **/
  14. @Configuration
  15. public class BeansConfig {
  16. @Bean
  17. public Calendar calendar(){
  18. return Calendar.getInstance();
  19. }
  20. }
2.TestController.java
  1. import com.christy.service.TestService;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. import java.util.Calendar;
  9. /**
  10. * @Author Christy
  11. * @Date 2021/9/1 11:06
  12. **/
  13. @RestController
  14. @RequestMapping("test")
  15. public class TestController {
  16. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  17. @Value("${server.port}")
  18. private Integer port;
  19. /**
  20. * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式
  21. */
  22. /*@Autowired
  23. private TestService testService;*/
  24. private TestService testService;
  25. private Calendar calendar;
  26. @Autowired
  27. public TestController(TestService testService, Calendar calendar){
  28. this.testService = testService;
  29. this.calendar = calendar;
  30. }
  31. @RequestMapping("hello")
  32. public String sayHello(){
  33. log.info(testService.sayHello());
  34. return testService.sayHello() + "current time is " + calendar.getTime();
  35. }
  36. }
3.测试

属性注入

基本属性注入

基本属性注入又称单个属性注入,使用注解@Value可以注入八大基本类型String日期ListArrayMap。下面我们来举例说明

1.application-dev.yml
  1. # 开发环境端口号是8802
  2. server:
  3. port: 8802
  4. # 基本类型
  5. username: christy
  6. age: 18
  7. salary: 1800
  8. gender: true
  9. birthday: 2003/10/01 #日期类型必须是yyyy/MM/dd这种斜线类型的
  10. # array、list与map
  11. hobbya: money,belle,right
  12. hobbyl: 抽烟,喝酒,烫头
  13. hobbym: "{'username':'christy','realname':'tide'}"
2.TestController.java
  1. import org.slf4j.Logger;
  2. import org.slf4j.LoggerFactory;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import java.util.Calendar;
  8. import java.util.Date;
  9. import java.util.List;
  10. import java.util.Map;
  11. /**
  12. * @Author Christy
  13. * @Date 2021/9/1 11:06
  14. **/
  15. @RestController
  16. @RequestMapping("test")
  17. public class TestController {
  18. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  19. // 注入基本数据类型、String、Date
  20. @Value("${username}")
  21. private String username;
  22. @Value("${age}")
  23. private Integer age;
  24. @Value("${gender}")
  25. private Boolean gender;
  26. @Value("${salary}")
  27. private Double salary;
  28. @Value("${birthday}")
  29. private Date birthday;
  30. // 注入数组
  31. @Value("${hobbya}")
  32. private String[] hobbya;
  33. // 注入list
  34. @Value("${hobbyl}")
  35. private List<String> hobbyl;
  36. // 注入map
  37. @Value("#{${hobbym}}")
  38. private Map<String,String> hobbym;
  39. /**
  40. * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式
  41. */
  42. /*@Autowired
  43. private TestService testService;*/
  44. private TestService testService;
  45. private Calendar calendar;
  46. @Autowired
  47. public TestController(TestService testService, Calendar calendar){
  48. this.testService = testService;
  49. this.calendar = calendar;
  50. }
  51. @RequestMapping("hello")
  52. public String sayHello(){
  53. log.info(testService.sayHello());
  54. System.out.println("姓名:" + username + ",年龄:" + age + ",性别:" + gender + ",生日:" + birthday + ",薪资:" + salary);
  55. System.out.println("生平三大爱好:");
  56. for (String hobby : hobbya) {
  57. System.out.print(hobby + "、");
  58. }
  59. System.out.println("生平三大爱好:");
  60. hobbyl.forEach(hobby-> System.out.println(hobby + "、"));
  61. System.out.println("map遍历");
  62. hobbym.forEach((key,value)-> System.out.println("key = " + key+" value = "+value));
  63. return testService.sayHello() + "current time is " + calendar.getTime();
  64. }
  65. }
3.测试

启动项目,在浏览器中访问http://localhost:8802/test/hello,观察控制台。如下图所示:

对象注入

1.application-dev.yml
  1. # 开发环境端口号是8802
  2. server:
  3. port: 8802
  4. # 基本类型
  5. username: christy
  6. age: 18
  7. salary: 1800
  8. gender: true
  9. birthday: 2003/10/01 #日期类型必须是yyyy/MM/dd这种斜线类型的
  10. # array、list与map
  11. hobbya: money,belle,right
  12. hobbyl: 抽烟,喝酒,烫头
  13. hobbym: "{'username':'christy','realname':'tide'}"
  14. # 注入对象
  15. user:
  16. name: christy
  17. age: 18
  18. bir: 2003/10/01
2.User.java
  1. import org.springframework.boot.context.properties.ConfigurationProperties;
  2. import org.springframework.stereotype.Component;
  3. import java.util.Date;
  4. /**
  5. * @Author Christy
  6. * @Date 2021/9/1 16:21
  7. * @ConfigurationProperties 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
  8. * prefix = "xxx":配置文件中哪个下面的所有属性进行一一映射
  9. * 使用该注解记得要写getter与setter方法
  10. **/
  11. @Component
  12. @ConfigurationProperties(prefix = "user")
  13. public class User {
  14. private String username;
  15. private Integer age;
  16. private Date birthday;
  17. public User() {
  18. }
  19. public User(String username, Integer age, Date birthday) {
  20. this.username = username;
  21. this.age = age;
  22. this.birthday = birthday;
  23. }
  24. public String getUsername() {
  25. return username;
  26. }
  27. public void setUsername(String username) {
  28. this.username = username;
  29. }
  30. public Integer getAge() {
  31. return age;
  32. }
  33. public void setAge(Integer age) {
  34. this.age = age;
  35. }
  36. public Date getBirthday() {
  37. return birthday;
  38. }
  39. public void setBirthday(Date birthday) {
  40. this.birthday = birthday;
  41. }
  42. @Override
  43. public String toString() {
  44. return "User{" +
  45. "username='" + username + '\'' +
  46. ", age=" + age +
  47. ", birthday=" + birthday +
  48. '}';
  49. }
  50. }
3.TestController.java
  1. import com.christy.entity.User;
  2. import com.christy.service.TestService;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import java.util.Calendar;
  10. import java.util.Date;
  11. import java.util.List;
  12. import java.util.Map;
  13. /**
  14. * @Author Christy
  15. * @Date 2021/9/1 11:06
  16. **/
  17. @RestController
  18. @RequestMapping("test")
  19. public class TestController {
  20. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  21. // 注入基本数据类型、String、Date
  22. @Value("${username}")
  23. private String username;
  24. @Value("${age}")
  25. private Integer age;
  26. @Value("${gender}")
  27. private Boolean gender;
  28. @Value("${salary}")
  29. private Double salary;
  30. @Value("${birthday}")
  31. private Date birthday;
  32. // 注入数组
  33. @Value("${hobbya}")
  34. private String[] hobbya;
  35. // 注入list
  36. @Value("${hobbyl}")
  37. private List<String> hobbyl;
  38. // 注入map
  39. @Value("#{${hobbym}}")
  40. private Map<String,String> hobbym;
  41. /**
  42. * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式
  43. */
  44. /*@Autowired
  45. private TestService testService;*/
  46. private TestService testService;
  47. private Calendar calendar;
  48. private User user;
  49. @Autowired
  50. public TestController(TestService testService, Calendar calendar, User user){
  51. this.testService = testService;
  52. this.calendar = calendar;
  53. this.user = user;
  54. }
  55. @RequestMapping("hello")
  56. public String sayHello(){
  57. log.info(testService.sayHello());
  58. System.out.println("姓名:" + username + ",年龄:" + age + ",性别:" + gender + ",生日:" + birthday + ",薪资:" + salary);
  59. System.out.println("生平三大爱好:");
  60. for (String hobby : hobbya) {
  61. System.out.print(hobby + "、");
  62. System.out.println();
  63. }
  64. System.out.println("生平三大爱好:");
  65. hobbyl.forEach(hobby-> System.out.println(hobby + "、"));
  66. System.out.println("map遍历");
  67. hobbym.forEach((key,value)-> System.out.println("key = " + key+" value = "+value));
  68. System.out.println(user.toString());
  69. return testService.sayHello() + "current time is " + calendar.getTime();
  70. }
  71. }
4.测试

启动项目,在浏览器中访问http://localhost:8802/test/hello,观察控制台。如下图所示:

5.警告

在使用注解@ConfigurationProperties的时候在User.java文件的上方有一个警告Spring Boot Configuration Annotation Processor not Configured。当然了他不影响我们程序的执行,但它是什么意思呢?

问题分析

它的意思是"Spring Boot的配置注解执行器没有配置",配置注解执行器的好处是什么?

配置注解执行器配置完成后,当执行类中已经定义了对象和该对象的字段后,在配置文件中对该类赋值时,便会非常方便的弹出提示信息。

解决方案

我们在pom.xml文件中加入以下依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-configuration-processor</artifactId>
  4. <!-- 为true时表示该依赖不会传递 -->
  5. <optional>true</optional>
  6. </dependency>

当加入该依赖后点击重新加载Maven依赖,原先的警告会消失,进而提示我们Re-run Spring Boot Configuration Annotation Processor to update generated metedata。如下图所示:

我们重启项目,然后回到配置文件,在配置文件中键入user,可以发现会自动提示User.java实体类中定义的属性

相关文章