springboot学习(六)事务与aop

本博文为系列文章建议大家从头阅读

  1. mysql事务
    事务我们当然是使用注解的方式,请不要问为什么
    经过前几节的配置我们只需在方法上加上@Transaction注解即可使用springboot的事务,不需要引spring-boot-starter-aop
    关于事务的超时时间可以参考:spring事务超时时间测试
    事务的传播行为(这个讲得很好):Spring事务传播行为详解

  2. 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
发布了52 篇原创文章 · 获赞 7 · 访问量 3823

猜你喜欢

转载自blog.csdn.net/maomaoqiukqq/article/details/98784201