自我复习springaop(二)

springAOP

连接点(join point):能被拦截器拦截的方法。
切点(pointcut):真正被拦截的方法。

​ 注意:切点一定是连接点,而连接点不一定是切点,因为连接点有可能不被拦截,从而不进行增强。

通知(advice):拦截器中的方法。分为前置通知,后置通知(也称最终通知),返回通知,异常通知,环绕通知五类。以反射执行目标对象方法为基准:

  • 前置通知:在目标对象方法执行之前执行;
  • 后置通知(最终通知):在目标对象方法执行完成后,无论在执行过程中是否出现异常,都会执行;
  • 异常通知:目标对象方法执行过程中产生异常后执行;
  • 返回通知:目标对象方法执行过程中不产生异常时执行;
  • 环绕通知:特殊的通知,不以目标对象方法为基准,可以同时实现前置和后置通知。环绕通知保留了调度目标对象原有方法的功能,也就是说,使用环绕通知甚至可以不必要调用目标对象方法,可以取代目标对象的方法。因此环绕通知非常强大,而且灵活,但可控性差,一般不需要大量改变业务逻辑的情况下,不会使用环绕通知。
    切面(aspect):通知与切点的结合。
    织入(weaving):将通知组合到目标的过程。
    引入(introduction):允许在现有类中添加自定义的类和方法。

记住这个就行:

Before 方法前
AfterReturning 方法返回之后
AfterThrowing 在异常抛出后
After finally执行
Around 环绕通知

**
     * 性能监测
     * @return
     */
    @Around("logPointcut()")
    public Object performanceAdvice(ProceedingJoinPoint pjp){
        //方法执行前处理

        // --- 调用被拦截的方法,执行连接点(方法)---
        //方法签名
        Signature signature = pjp.getSignature();
        //得到参数
        Object[] args = pjp.getArgs();

        System.out.println("进入方法"+signature+" 参数为"+ Arrays.toString(args));

        try {
            long before = System.currentTimeMillis();
            //得到了方法调用的参数
            Object result = pjp.proceed(args);
            long after = System.currentTimeMillis();
            System.out.println("执行时长为:"+(after-before)+"ms");
            return result;
        } catch (Throwable t) {
            throw new RuntimeException(t);
        }

        //方法执行后处理

    }

在这里插入图片描述
手写声明式事务
定义事务注解 @Tx
定义切面:
• 切入点是所有加了Tx注解的方法;
• 通知选用环绕类型
• 方法执行前开启事务
• 执行方法
• 提交或者回滚事务

第一步:加依赖

  <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--        数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.22</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
        <!--        mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>
        <!--  将mybatis集成到spring中  -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.5</version>
        </dependency>

第二步:拷贝代码,拷贝配置文件,拷贝配置类,修改配置,导入配置类
第三步:定义注解

package com.woniuxy.framework.annotations;

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Tx {
}

第四步:定义切面

package com.woniuxy.framework.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

@Component
@Aspect
public class TxAspect {

    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    /**
     * 拦截所有加入了@Tx注解的方法
     */
    @Pointcut("@annotation(com.woniuxy.framework.annotations.Tx)")
    public void txPointcut(){}

    /**
     * 事务通知
     * @param pjp
     * @return
     */
    @Around("txPointcut()")
    public Object txAdvice(ProceedingJoinPoint pjp){
        //1.开启事务
        TransactionStatus txStatus = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());

        //2.调用方法
        Object[] args = pjp.getArgs();
        Object result = null;
        try {
            result = pjp.proceed(args);
        } catch (Throwable throwable) {
            //3.1 回滚
//            throwable.printStackTrace();
            System.out.println("事务出现异常,回滚");
            platformTransactionManager.rollback(txStatus);
            throw new RuntimeException(throwable);
        }
        //3.2 提交
        System.out.println("事务处理完成,提交");
        platformTransactionManager.commit(txStatus);
        return result;

    }
}

最后测试:

 CourseService courseService = ctx.getBean(CourseService.class);
        Course course = new Course();
        course.setCourseName("Java入门");
        course.setCategory("Java");
        course.setPrice(10.0D);
        course.setSvipPrice(10.0D);
        course.setVideoType("xx");
        course.setChargeType("");
        course.setPurchaseCount(0);
        course.setStudyCount(0);
        course.setDescription("");
        course.setImage("");
        course.setTeacherId(0);
        course.setTeacherName("");
        course.setTeacherDesc("");
        course.setTeacherAvatar("");

        Chapter chapter = new Chapter();
        chapter.setTitle("万物皆对象");
        chapter.setChapterOrder(1);

        List<Chapter> chapters = Arrays.asList(chapter);

        courseService.addCourse(course,chapters);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小小刘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值