本博文为系列文章建议大家从头阅读
-
mysql事务
事务我们当然是使用注解的方式,请不要问为什么
经过前几节的配置我们只需在方法上加上@Transaction注解即可使用springboot的事务,不需要引spring-boot-starter-aop
关于事务的超时时间可以参考:spring事务超时时间测试
事务的传播行为(这个讲得很好):Spring事务传播行为详解 -
aop,我们这里只演示最常用的注解方式, 其它方式及aspectj表达式请自己查阅资料
//@Around("@annotation(com.hero.study.aop.PrintLog)")//增强注解修饰的方法
@Around("@within(com.hero.study.aop.PrintLog)")//增强注解修饰的类
第一步当然在pom中引入aop模块:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第二步自定义一个注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PrintLog {
}
(ElementType)取值有:
1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
(ElementType)取值有:
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
第三步,创建一个切面类
@Configuration
@Aspect
public class PrintLogAop {
@Before("@within(com.hero.study.aop.PrintLog)")
public void before(JoinPoint joinPoint) {
System.out.println("==== aop before");
}
@After("@within(com.hero.study.aop.PrintLog)")
public void after(JoinPoint joinPoint) {
System.out.println("==== aop after");
}
@AfterThrowing("@within(com.hero.study.aop.PrintLog)")
public void afterThrowing(JoinPoint joinPoint) {
System.out.println("==== aop afterThrowing");
}
//@Around("@annotation(com.hero.study.aop.PrintLog)")//增强注解修饰的方法
@Around("@within(com.hero.study.aop.PrintLog)")//增强注解修饰的类
public Object simpleAop(final ProceedingJoinPoint pjp) throws Throwable {
try {
String methodName = pjp.getSignature().getName();
String className = pjp.getSignature().getDeclaringType().getName();
Object[] args = pjp.getArgs();
System.out.println("====类:" + className + ",方法:" + methodName + ",入参:" + Arrays.toString(args));
Object proceed = pjp.proceed();
System.out.println("====类:" + className + ",方法:" + methodName + ",出参:" + proceed);
return proceed;
} catch (Throwable throwable) {
throwable.printStackTrace();
throw throwable;
}
}
}
第四步:在我们之前的Service类上加@PrintLog注解
注意区别: //@Around("@annotation(com.hero.study.aop.PrintLog)")//增强注解修饰的方法
@Around("@within(com.hero.study.aop.PrintLog)")//增强注解修饰的类
在测试类中添加测试方法
@Test
public void select() {
try {
User user = userService.selectByPrimaryKey(20);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
}
运行测试方法控制台打印如下(通过这个测试我们可以知道@Befor@After@Around的执行顺序):
====类:com.hero.study.service.Impl.UserServiceImpl,方法:selectByPrimaryKey,入参:[20]
==== aop before
====类:com.hero.study.service.Impl.UserServiceImpl,方法:selectByPrimaryKey,出参:User [Hash = 104634049, id=20, name=name, password=y, serialVersionUID=1]
==== aop after