服务是Springboot的组件之一,一般用于完成一些数据的校验、加工的操作,也可以被定义为工具:
用户发送请求后,控制层接收请求,并将指定业务分发给服务层,服务器从持久层(操作数据库等)拿到数据,进行业务处理(或直接进行处理),再将结果发回给控制层。
服务类一般放在service包下
@Service注解
基本用法
Service注解用于标注一个服务类,同样在内部有一个@Component注解:
@Service
class TestService {
// 服务类的方法
}
在一些大型项目里,会将服务类写成接口的形式,再在service包下创建一个impl包,在这个包里面创建服务的实现类,并用@Service标注:
interface TestService {
// 服务类的抽象方法
}
@Service
class TestServiceImpl : TestService{
// 重写服务方法
}
使用服务类时,可以通过@Autowired注解标注一个服务类变量,项目运行时会自动注入一个服务类的对象:
@Autowired
lateinit var testService: TestService
接下来就可以使用这个对象调用服务类的方法了
我们来举个例子,用服务类实现用户名和密码的检测功能:
创建一个service包,在service包下创建一个TestService接口:
package com.example.c0101.service
interface TestService {
fun check(username: String, password: String): Boolean
}
再在service包下创建一个impl包,在impl包下创建一个TestServiceImpl的类:
package com.example.c0101.service.impl
import com.example.c0101.service.TestService
import org.springframework.stereotype.Service
@Service
class TestServiceImpl : TestService{
override fun check(username: String, password: String): Boolean {
return username == "admin" && password == "123456"
}
}
在创建一个controller包,在controller包下创建一个TestController类:
package com.example.c0101.controller
import com.example.c0101.service.TestService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class TestController {
@Autowired
lateinit var testService: TestService
@RequestMapping("/login")
fun login(username: String, password: String): String{
return if (testService.check(username, password)) "登录成功" else "登录失败"
}
}
用postman访问一下:
多个服务实现类的情况
服务的实现类可以有多个,但这样会起冲突,因此我们可以定义每个实现类的别名:
@Service("admin")
class TestServiceImpl : TestService{
override fun check(username: String, password: String): Boolean {
return username == "admin" && password == "123456"
}
}
定义别名可以通过向@Service传参的方式
在注入时,可以通过@Qualifier注解设置别名:
@Autowired
@Qualifier("admin")
lateinit var testServiceAdmin: TestService
在service.impl包下创建一个TestServiceImpl2类:
package com.example.c0101.service.impl
import com.example.c0101.service.TestService
import org.springframework.stereotype.Service
@Service("zhangsan")
class TestServiceImpl2 : TestService {
override fun check(username: String, password: String): Boolean {
return username == "zhangsan" && password == "password"
}
}
给TestServiceImpl的@Service传入一个别名:
package com.example.c0101.service.impl
import com.example.c0101.service.TestService
import org.springframework.stereotype.Service
@Service("admin")
class TestServiceImpl : TestService{
override fun check(username: String, password: String): Boolean {
return username == "admin" && password == "123456"
}
}
修改TestController:
package com.example.c0101.controller
import com.example.c0101.service.TestService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class TestController {
@Autowired
@Qualifier("admin")
lateinit var testServiceAdmin: TestService
@Autowired
@Qualifier("zhangsan")
lateinit var testServiceZhangsan: TestService
@RequestMapping("/login/admin")
fun login(username: String, password: String): String{
return if (testServiceAdmin.check(username, password)) "登录成功" else "登录失败"
}
@RequestMapping("/login/zhangsan")
fun login2(username: String, password: String): String{
return if (testServiceZhangsan.check(username, password)) "登录成功" else "登录失败"
}
}
可以看到,我们在/login/admin下使用admin的服务,在/login/zhangsan下使用zhangsan的服务
用postman测试一下: