8. Spring Boot Service¶
8.1. 理解 Service¶
Service Components are the class file which contains @Service annotation. These class files are used to write business logic in a different layer.
8.2. @Autowired¶
Inject list of all beans with a certain interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @Component
public class SomeComponent {
interface SomeInterface {
}
@Component
class Impl1 implements SomeInterface {
}
@Component
class Impl2 implements SomeInterface {
}
@Autowired
private List<SomeInterface> listOfImpls;
}
|
8.3. 类中获取属性数据¶
8.3.1. @ConfigurationProperties¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @PropertySource("classpath:dbconfig.properties")
@ConfigurationProperties("database")
public class DatabaseConfiguration {
@Length(min=2, max=10)
private String name;
@NotEmpty
private String url;
@Length(min=5, max=10)
@Pattern(regexp = "[a-z-A-Z]*", message = "Username can not contain invalid characters")
private String username;
@Length(min=8, max=16)
private String password;
}
|
- @PropertySource 标签是指定属性文件,默认是application.yml 或 application.properties
- @ConfigurationProperties 标签指定属性文件中的属性前缀
8.3.2. @Value¶
This annotation can be used for injecting values into fields in Spring-managed beans and it can be applied at the field or constructor/method parameter level.
8.4. Error Handling for REST¶
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Actor Not Found")
public class ActorNotFoundException extends Exception {
}
@GetMapping("/actor/{id}")
public String getActorName(@PathVariable("id") int id) {
try {
return actorService.getActor(id);
} catch (ActorNotFoundException ex) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Actor Not Found", ex);
}
}
8.5. Spring boot自定义注解¶
1 2 3 4 5 | <!-- AOP依赖模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
|
8.5.1. 使用自定义注解来统计方法的执行时间¶
8.5.1.1. 创建@AnalysisActuator¶
1 2 3 4 5 6 7 8 9 10 11 12 | package com.example.demo.aop;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnalysisActuator {
String note() default "";
}
|
8.5.1.2. 创建Aspect¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package com.example.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AnalysisActuatorAspect {
final static Logger log = LoggerFactory.getLogger(AnalysisActuatorAspect.class);
ThreadLocal<Long> beginTime = new ThreadLocal<>();
@Pointcut("@annotation(analysisActuator)")
public void serviceStatistics(AnalysisActuator analysisActuator) {
}
@Before("serviceStatistics(analysisActuator)")
public void doBefore(JoinPoint joinPoint, AnalysisActuator analysisActuator) {
// 记录请求到达时间
beginTime.set(System.currentTimeMillis());
log.info("------ note:{}", analysisActuator.note());
}
@After("serviceStatistics(analysisActuator)")
public void doAfter(AnalysisActuator analysisActuator) {
log.info("------ statistic time:{}, note:{}", System.currentTimeMillis() - beginTime.get(),
analysisActuator.note());
}
}
|
8.5.1.3. 使用¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package com.example.demo.controller;
import java.util.Optional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.aop.AnalysisActuator;
@RestController
public class HelloWorldController {
@GetMapping("/")
@AnalysisActuator(note = "HelloWorldController中的hello方法")
public String hello(String name) {
return "Hello " + Optional.ofNullable(name).orElse("World!");
}
}
|
调用地址:http://localhost:8080/?name=Java 屏幕打印:
2019-10-22 15:21:18.512 INFO 22521 --- [nio-8080-exec-1] c.e.demo.aop.AnalysisActuatorAspect
: ------ note:HelloWorldController中的hello方法
2019-10-22 15:21:18.550 INFO 22521 --- [nio-8080-exec-1] c.e.demo.aop.AnalysisActuatorAspect
: ------ statistic time:38, note:HelloWorldController中的hello方法