一、使用@ConfigurationProperties代替@Value 

我们之前使用配置文件中的属性的时候使用@Value注解来注入。

配置文件如下:

书写Java的一些好习惯_spring

我们创建一个控制器使用@Value注解引入它们

package com.example.myspringboot.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author qx
 * @date 2023/7/7
 * @des 测试控制器
 */
@RestController
public class StudentController {

    @Value("${student.name}")
    private String name;

    @Value("${student.age}")
    private Integer age;


    @GetMapping("/")
    public void show() {
        // 输出name:lisi
        System.out.println("name:" + name);
        // 输出age:20
        System.out.println("age:" + age);
    }
}

我们发现如果只有一两个属性还好处理,如果有很多属性需要导入的话,我们一个个导入就很麻烦了,所以我们需要@ConfigurationProperties注解来

统一导入,prefix属性来指定公共的属性部分。

我们创建一个配置类:

package com.example.myspringboot.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author qx
 * @date 2023/7/7
 * @des
 */
@Component
@ConfigurationProperties(prefix = "student")
@Getter
@Setter
public class StudentConfig {

    private String name;

    private Integer age;
}

里面的成员变量对应配置文件的属性名。

控制器使用:

package com.example.myspringboot.controller;

import com.example.myspringboot.config.StudentConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author qx
 * @date 2023/7/7
 * @des 测试控制器
 */
@RestController
@RequiredArgsConstructor
public class StudentController {

    final StudentConfig studentConfig;


    @GetMapping("/")
    public void show() {
        System.out.println(studentConfig.getName());
        System.out.println(studentConfig.getAge());
    }

}

启动服务,访问地址,控制台显示如下:

2023-07-07 11:16:12.810  INFO 9948 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-07-07 11:16:12.810  INFO 9948 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-07-07 11:16:12.811  INFO 9948 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
lisi
20

二、使用@RequiredArgsConstructor代替@Autowired 

我们都知道注入一个bean有三种方式(set注入, 构造器注入, 注解注入),spring推荐我们使用构造器的方式注入Bean。

上一节我们的控制层使用@RequiredArgsConstructor注入我们的bean

package com.example.myspringboot.controller;

import com.example.myspringboot.config.StudentConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author qx
 * @date 2023/7/7
 * @des 测试控制器
 */
@RestController
@RequiredArgsConstructor
public class StudentController {

    final StudentConfig studentConfig;


    @GetMapping("/")
    public void show() {
        System.out.println(studentConfig.getName());
        System.out.println(studentConfig.getAge());
    }


}

我们在编译的文件中,发现是通过构造器的方式注入bean的。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.example.myspringboot.controller;

import com.example.myspringboot.config.StudentConfig;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StudentController {
    final StudentConfig studentConfig;

    @GetMapping({"/"})
    public void show() {
        System.out.println(this.studentConfig.getName());
        System.out.println(this.studentConfig.getAge());
    }

    public StudentController(final StudentConfig studentConfig) {
        this.studentConfig = studentConfig;
    }
}

三、代码模块化

我们要保证一个方法只处理一种逻辑或业务,拆分我们的 接口和方法,让代码模块化。


四、异常不返回而是抛出

 public void importEmployee(MultipartFile file) throws IOException {
        if (null == file || file.isEmpty()) {
            // 抛出异常
            CommonUtil.throwMsg("上传的文件不能为空");
        }
        EasyExcel.read(file.getInputStream(), EmployeeExcel.class, new EmployeeListener(this)).sheet().doRead();
    }

五、不返回null

public List<Student> getStudentList() {
        // 不要返回return null
        return Collections.emptyList();
    }

别处调用方法时,避免不必要的空指针

六、减少controller业务代码

业务代码尽量放到service层进行处理

七、利用好Idea

idea会对我们的代码进行判断,提出合理的建议

八、使用Optional解决空指针问题

public Student getData(){
       Student student = null;
       return Optional.ofNullable(student).orElse(new Student());
   }

九、解决重复元素使用HashSet


    @Test
    void contextLoads() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(1);
        list.add(3);
        Set<Integer> set = new HashSet<>(list);
        // 输出[1, 2, 3]
        System.out.println(set);
    }

十、遍历集合推荐用法

  @Test
    void contextLoads() {
        // 推荐的Map遍历方式使用entrySet
        Map<String, String> map = new HashMap<>();
        map.put("name", "qq");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }

        // 集合遍历删除元素 使用iterator
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (2 == iterator.next()) {
                iterator.remove();
            }
        }
        // 输出[1, 3]
        System.out.println(list);
    }

十一、减少不必要的db

尽可能的减少对数据库的查询,对于一个方法中都需要的同一份数据,我们可以把这一份数据提取到都可以访问到的地方,不用重复去查询。