jck28 - 小柒 - 后端接口基本开发 - spring boot高级注解

一, @service注解

1.1 背景

  • 所有的请求业务逻辑不写在controller的类内,需要写在业务层service层

1.2 实现步骤

    1. 创建处理业务逻辑的包service
    1. 在包下创建业务接口 UserService
package com.ceshiren.springtest.service;

import com.ceshiren.springtest.dto.UserDto;

public interface UserService {

    //用户登录接口
    String login(UserDto userDto);

    //用户注册接口
    String registerAndParam(UserDto userDto, String module, String desc , String age);

}
    1. 创建对应接口的实现类,编写具体的业务逻辑 ,实现类上添加注解@Service
  • @Service放在接口上

    • 明确表明接口只能用于服务级别目的
    • 定义新的服务实现并在启动期间将它们自动检测为 Spring bean
package com.ceshiren.springtest.service;

import com.ceshiren.springtest.dto.UserDto;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService{
    @Override
    public String login(UserDto userDto) {
        if(userDto.getUsername().equals("demi") && userDto.getPassword().equals("123456")){
            return "用户登录成功!用户名:" + userDto.getUsername() + ", 密码:" +userDto.getPassword();
        }else{
            return "用户登录失败!用户名:" + userDto.getUsername() + ", 密码:" +userDto.getPassword();
        }
    }

    @Override
    public String registerAndParam(UserDto userDto, String module, String desc, String age) {
        return null;
    }
}
    1. PostController类内注入业务接口实体类: @Autowired
    1. Controller 的方法内直接调用UserService的具体方法
@RestController
public class PostController {

    //Autowired注解,实例化对象作为容器注入进来
    @Autowired
    UserService userService;

    @PostMapping(value = "/login", produces = "application/json")
    String login(@RequestBody UserDto userDto){
        return userService.login(userDto);
    }

    1. 启动服务,postman输入验证
    1. 总结
    • @Service注释放在接口上没有任何效果
    • 只有具体类在使用@Service注释时才会被组件扫描

二, @Autowired注解

2.1 含义:

    1. 对属性、设置器和构造器使用自动装配
    1. 若容器中有多个相同类型的 bean,框架将抛出异常
    • 明确地告诉 Spring 我们要注入哪个 bean

2.2 使用:

  • 在容器中查询对应类型的bean
    • 若查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
    • 若查询的结果不止一个,那@Autowired根据名称来查找
    • 若查询的结果为空,则会抛出异常NoUniqueBeanDefinitionException

2.3 示例 :

  • 当一个接口有多个实现类的情况下,启动spring boot会报错,在controller类中该如何注入?

(1)解决方法一:

  • Service加别名指定: @Service("userp")
  • @Qualifier 注解缩小实现范围,指定对应别名作为容器注入
    //Autowired注解,实例化对象作为容器注入进来
    @Autowired
    @Qualifier("userp")
    UserService userService;

(2)解决方法二:

  • Service加别名指定
  • Autowired注入的bean名为Service具体实现类的别名
    @Autowired
    UserService userp;

(3)解决方法三:

  • Service加指定首选项注解 @Primary
@Service("user")
@Primary
public class UserServiceImpl implements UserService{
    @Override
    public String login(UserDto userDto) {
        if(userDto.getUsername().equals("demi") && userDto.getPassword().equals("123456")){
            return "用户登录成功!用户名:" + userDto.getUsername() + ", 密码:" +userDto.getPassword();
        }else{
            return "用户登录失败!用户名:" + userDto.getUsername() + ", 密码:" +userDto.getPassword();
        }
    }
}

注意:

  • @Qualifier注解优先级要高于@Primary注解
    • @Primary定义了一个默认值,而@Qualifier非常具体

三, 配置类注解

3.1 @Value 注解

  • (1)application配置文件自定义配置:
android.deviceName=abdc423579
  • (2)定义一个参数,加上 @Value 注解,注解内容为"${自定义的key}"
@RestController
//RequestMapping在类上的注解,表示提取请求的共同路径
@RequestMapping("/t")
public class FirstController {
    //配置文件对应的key的内容,需要用$()把自定义的key包裹起来;   $() - 用于加载外部属性文件中的值
    @Value("${android.deviceName}")
    private String deviceName;


//    @GetMapping("/first")
    @RequestMapping(path="/first", method = RequestMethod.GET)
    String first(){
        System.out.println("配置文件的值:" + deviceName);

        return "hello spring boot !" ;
    }
  • (3)当配置文件没有该配置时,定义默认值
    //配置文件对应的key的内容,需要用$()把自定义的key包裹起来;   $() - 用于加载外部属性文件中的值
    //  wechat123为取不到值时的默认值
    @Value("${android.deviceName:wechat123}")
    private String deviceName;

3.2 @Configuration 注解

  • (1)创建配置文件application.properties

  • (2)在配置文件中编写对应 jdbc连接配置

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://
jdbc.username=root
jdbc.password=root
  • (3)代码中创建配置实体类,根据 key 获取对应 value

  • (4)配置实体类需要Configuration注解和Bean注解

package com.ceshiren.springtest.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;

//配置类注解
@Configuration
public class JdbcConfiguration {
    //ads-communal为取不到值时的默认值
    @Value("${jdbc.driverClassName:ads-communal}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public HashMap<String,String> getJdbc(){
        HashMap<String,String> hashMap = new HashMap<>() {
            {
                put("driverClassName",driverClassName);
                put("url",url);
                put("username",username);
                put("password",password);
            }
        };
        return hashMap;
    }

}


  • (5)controller对应调用
package com.ceshiren.springtest.controller;

import com.ceshiren.springtest.config.JdbcConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;

@RestController
public class ValueController {
    @Autowired
    JdbcConfiguration jdbcConfiguration;

    @GetMapping(value = "/getJdbc",produces = "application/json")
    HashMap<String,String> getJdbc(){
        return jdbcConfiguration.getJdbc();
    }

}