如果這是你第二次看到師長,說明你在覬覦我的美色!
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比蜀山網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式蜀山網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋蜀山地區(qū)。費(fèi)用合理售后完善,十余年實(shí)體公司更值得信賴。
點(diǎn)贊+關(guān)注再看,養(yǎng)成習(xí)慣
沒別的意思,就是需要你的窺屏^_^
該趟專車是開往基于Spring Boot事務(wù)思想實(shí)戰(zhàn)的專車,在上一篇 搭上SpringBoot事務(wù)源碼分析專車[1]中我們詳細(xì)介紹了Spring Boot事務(wù)實(shí)現(xiàn)的原理,這一篇是基于上一篇的實(shí)戰(zhàn)。
在實(shí)戰(zhàn)之前,我們再次回顧下上篇文章講解的重點(diǎn):
實(shí)現(xiàn)是以Spring Boot為基礎(chǔ),需要添加如下依賴
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
按照如上提到的問題依次定義
定義bean后置處理器,特別注意,如果項目中使用到了事務(wù)特性,就不需要重復(fù)定義
/**
* 一定要聲明InfrastructureAdvisorAutoProxyCreator,用于實(shí)現(xiàn)bean的后置處理
*
* @return
*/
@Bean
public InfrastructureAdvisorAutoProxyCreator infrastructureAdvisorAutoProxyCreator() {
return new InfrastructureAdvisorAutoProxyCreator();
}
定義切面
public class BeanFactorySystemLogAdvisor extends AbstractBeanFactoryPointcutAdvisor {
/**
* 定義切點(diǎn)
*/
private final SystemLogPointcut point = new SystemLogPointcut();
@Override
public Pointcut getPointcut() {
return this.point;
}
}
定義切點(diǎn)
public class SystemLogPointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, Class> targetClass) {
// 查找類上@SystemLog注解屬性
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
targetClass, SystemLog.class, false, false);
if (Objects.nonNull(attributes)) {
return true;
}
// 查找方法上@SystemLog注解屬性
attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
method, SystemLog.class, false, false);
return Objects.nonNull(attributes);
}
}
定義通知
@Slf4j
public class SystemLogInterceptor implements MethodInterceptor, Serializable {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
String className = method.getDeclaringClass().getSimpleName();
String methodName = method.getName();
log.info("======[" + className + "#" + methodName + " method begin execute]======");
Arrays.stream(invocation.getArguments()).forEach(argument -> log.info("======[execute method argument:" + argument + "]======"));
Long time1 = Clock.systemDefaultZone().millis();
Object result = invocation.proceed();
Long time2 = Clock.systemDefaultZone().millis();
log.info("======[method execute time:" + (time2 - time1) + "]======");
return result;
}
}
自動配置
@Configuration
public class ProxySystemLogConfiguration {
/**
* 定義切面
* 此處一定要指定@Role注解
*
* @return
*/
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Bean
public BeanFactorySystemLogAdvisor beanFactorySystemLogAdvisor() {
BeanFactorySystemLogAdvisor advisor = new BeanFactorySystemLogAdvisor();
advisor.setAdvice(systemLogInterceptor());
return advisor;
}
/**
* 定義通知
*
* @return
*/
@Bean
public SystemLogInterceptor systemLogInterceptor() {
return new SystemLogInterceptor();
}
/**
* 一定要聲明InfrastructureAdvisorAutoProxyCreator,用于實(shí)現(xiàn)bean的后置處理
*
* @return
*/
@Bean
public InfrastructureAdvisorAutoProxyCreator infrastructureAdvisorAutoProxyCreator() {
return new InfrastructureAdvisorAutoProxyCreator();
}
}
定義注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
}
定義控制器
@RestController
public class SystemLogController {
@Autowired
private SystemLogService systemLogService;
@GetMapping("/log")
public String hello(@RequestParam("name") String name) throws InterruptedException {
return systemLogService.log(name);
}
}
定義業(yè)務(wù)方法
@Slf4j
@Service
public class SystemLogService {
@SystemLog
public String log(String name) throws InterruptedException {
log.info("執(zhí)行業(yè)務(wù)方法");
TimeUnit.SECONDS.sleep(1);
return "hello " + name;
}
}
定義啟動類
@SpringBootApplication
public class TransactionImitateApplication {
public static void main(String[] args) {
SpringApplication.run(TransactionImitateApplication.class, args);
}
}
訪問http://localhost:8080/log?name=advisor
查看控制臺
2019-08-23 11:13:36.029 INFO 23227 --- [nio-8080-exec-1] c.b.example.config.SystemLogInterceptor : ======[SystemLogService#log method begin execute]======2019-08-23 11:13:36.030 INFO 23227 --- [nio-8080-exec-1] c.b.example.config.SystemLogInterceptor : ======[execute method argument:advisor]======2019-08-23 11:13:36.038 INFO 23227 --- [nio-8080-exec-1] c.boot.example.service.SystemLogService : 執(zhí)行業(yè)務(wù)方法2019-08-23 11:13:37.038 INFO 23227 --- [nio-8080-exec-1] c.b.example.config.SystemLogInterceptor : ======[method execute time:1004]======
可以看到通過模擬@Transaction注解的實(shí)現(xiàn)方式,完成了日志切面功能。
回顧下開頭的五個問題:
師長,專注分享Java進(jìn)階、架構(gòu)技術(shù)、高并發(fā)、微服務(wù)、BAT面試、redis專題、JVM調(diào)優(yōu)、Springboot源碼、MySQL優(yōu)化等20大進(jìn)階架構(gòu)專題。