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

x33g5p2x  于2021-09-19 转载在 Spring  
字(10.7k)|赞(0)|评价(0)|浏览(689)

前言

所谓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. /** * @Author Christy * @Date 2021/9/1 11:06 **/
  9. @RestController
  10. @RequestMapping("test")
  11. public class TestController {
  12. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  13. @Value("${server.port}")
  14. private Integer port;
  15. /** * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式 */
  16. /*@Autowired private TestService testService;*/
  17. private TestService testService;
  18. @Autowired
  19. public TestController(TestService testService){
  20. this.testService = testService;
  21. }
  22. @RequestMapping("hello")
  23. public String sayHello(){
  24. log.info(testService.sayHello());
  25. return testService.sayHello() + "current port is " + port;
  26. }
  27. }
2.TestService
  1. /** * @Author Christy * @Date 2021/9/1 14:25 **/
  2. public interface TestService {
  3. String sayHello();
  4. }
  5. import com.christy.service.TestService;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.stereotype.Service;
  9. /** * @Author Christy * @Date 2021/9/1 14:26 * @Service 该注解标识当前对象为一个业务处理对象,并将当前对象交由Spring管理,默认在Spring工厂的名字是类名首字母小写 **/
  10. @Service
  11. public class TestServiceImpl implements TestService {
  12. private static final Logger log = LoggerFactory.getLogger(TestServiceImpl.class);
  13. @Override
  14. public String sayHello() {
  15. log.info("Hello SpringBoot!");
  16. return "Hello SpringBoot!";
  17. }
  18. }
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. /** * @Author Christy * @Date 2021/9/1 14:57 * * @Configuration 标注在类上,作用:配置Spring容器(应用上下文),被它修饰的类表示可以使用Spring IoC容器作为bean定义的来源。 * 相当于把该类作为Spring的xml配置文件中的<beans>元素(并且包含命名空间) * 简单的理解,被该注解标识的类就相当于SSM框架中的Spring.xml * @Bean 标注在方法上,作用:注册bean对象,被标记的方法的返回值会作为bean被加入到Spring IoC容器之中,bean的名称默认为方法名。 * 相当于把该方法的返回值作为 xml 配置文件中<beans>的子标签<bean> **/
  5. @Configuration
  6. public class BeansConfig {
  7. @Bean
  8. public Calendar calendar(){
  9. return Calendar.getInstance();
  10. }
  11. }
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. /** * @Author Christy * @Date 2021/9/1 11:06 **/
  10. @RestController
  11. @RequestMapping("test")
  12. public class TestController {
  13. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  14. @Value("${server.port}")
  15. private Integer port;
  16. /** * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式 */
  17. /*@Autowired private TestService testService;*/
  18. private TestService testService;
  19. private Calendar calendar;
  20. @Autowired
  21. public TestController(TestService testService, Calendar calendar){
  22. this.testService = testService;
  23. this.calendar = calendar;
  24. }
  25. @RequestMapping("hello")
  26. public String sayHello(){
  27. log.info(testService.sayHello());
  28. return testService.sayHello() + "current time is " + calendar.getTime();
  29. }
  30. }
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. /** * @Author Christy * @Date 2021/9/1 11:06 **/
  12. @RestController
  13. @RequestMapping("test")
  14. public class TestController {
  15. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  16. // 注入基本数据类型、String、Date
  17. @Value("${username}")
  18. private String username;
  19. @Value("${age}")
  20. private Integer age;
  21. @Value("${gender}")
  22. private Boolean gender;
  23. @Value("${salary}")
  24. private Double salary;
  25. @Value("${birthday}")
  26. private Date birthday;
  27. // 注入数组
  28. @Value("${hobbya}")
  29. private String[] hobbya;
  30. // 注入list
  31. @Value("${hobbyl}")
  32. private List<String> hobbyl;
  33. // 注入map
  34. @Value("#{${hobbym}}")
  35. private Map<String,String> hobbym;
  36. /** * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式 */
  37. /*@Autowired private TestService testService;*/
  38. private TestService testService;
  39. private Calendar calendar;
  40. @Autowired
  41. public TestController(TestService testService, Calendar calendar){
  42. this.testService = testService;
  43. this.calendar = calendar;
  44. }
  45. @RequestMapping("hello")
  46. public String sayHello(){
  47. log.info(testService.sayHello());
  48. System.out.println("姓名:" + username + ",年龄:" + age + ",性别:" + gender + ",生日:" + birthday + ",薪资:" + salary);
  49. System.out.println("生平三大爱好:");
  50. for (String hobby : hobbya) {
  51. System.out.print(hobby + "、");
  52. }
  53. System.out.println("生平三大爱好:");
  54. hobbyl.forEach(hobby-> System.out.println(hobby + "、"));
  55. System.out.println("map遍历");
  56. hobbym.forEach((key,value)-> System.out.println("key = " + key+" value = "+value));
  57. return testService.sayHello() + "current time is " + calendar.getTime();
  58. }
  59. }
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. /** * @Author Christy * @Date 2021/9/1 16:21 * @ConfigurationProperties 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定; * prefix = "xxx":配置文件中哪个下面的所有属性进行一一映射 * 使用该注解记得要写getter与setter方法 **/
  5. @Component
  6. @ConfigurationProperties(prefix = "user")
  7. public class User {
  8. private String username;
  9. private Integer age;
  10. private Date birthday;
  11. public User() {
  12. }
  13. public User(String username, Integer age, Date birthday) {
  14. this.username = username;
  15. this.age = age;
  16. this.birthday = birthday;
  17. }
  18. public String getUsername() {
  19. return username;
  20. }
  21. public void setUsername(String username) {
  22. this.username = username;
  23. }
  24. public Integer getAge() {
  25. return age;
  26. }
  27. public void setAge(Integer age) {
  28. this.age = age;
  29. }
  30. public Date getBirthday() {
  31. return birthday;
  32. }
  33. public void setBirthday(Date birthday) {
  34. this.birthday = birthday;
  35. }
  36. @Override
  37. public String toString() {
  38. return "User{" +
  39. "username='" + username + '\'' +
  40. ", age=" + age +
  41. ", birthday=" + birthday +
  42. '}';
  43. }
  44. }
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. /** * @Author Christy * @Date 2021/9/1 11:06 **/
  14. @RestController
  15. @RequestMapping("test")
  16. public class TestController {
  17. private static final Logger log = LoggerFactory.getLogger(TestController.class);
  18. // 注入基本数据类型、String、Date
  19. @Value("${username}")
  20. private String username;
  21. @Value("${age}")
  22. private Integer age;
  23. @Value("${gender}")
  24. private Boolean gender;
  25. @Value("${salary}")
  26. private Double salary;
  27. @Value("${birthday}")
  28. private Date birthday;
  29. // 注入数组
  30. @Value("${hobbya}")
  31. private String[] hobbya;
  32. // 注入list
  33. @Value("${hobbyl}")
  34. private List<String> hobbyl;
  35. // 注入map
  36. @Value("#{${hobbym}}")
  37. private Map<String,String> hobbym;
  38. /** * Spring官方不再建议使用该种方式进行注入,转而使用构造函数的方式 */
  39. /*@Autowired private TestService testService;*/
  40. private TestService testService;
  41. private Calendar calendar;
  42. private User user;
  43. @Autowired
  44. public TestController(TestService testService, Calendar calendar, User user){
  45. this.testService = testService;
  46. this.calendar = calendar;
  47. this.user = user;
  48. }
  49. @RequestMapping("hello")
  50. public String sayHello(){
  51. log.info(testService.sayHello());
  52. System.out.println("姓名:" + username + ",年龄:" + age + ",性别:" + gender + ",生日:" + birthday + ",薪资:" + salary);
  53. System.out.println("生平三大爱好:");
  54. for (String hobby : hobbya) {
  55. System.out.print(hobby + "、");
  56. System.out.println();
  57. }
  58. System.out.println("生平三大爱好:");
  59. hobbyl.forEach(hobby-> System.out.println(hobby + "、"));
  60. System.out.println("map遍历");
  61. hobbym.forEach((key,value)-> System.out.println("key = " + key+" value = "+value));
  62. System.out.println(user.toString());
  63. return testService.sayHello() + "current time is " + calendar.getTime();
  64. }
  65. }
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实体类中定义的属性

相关文章