013,Spring Aop基于AspectJ开发

V哥官网:http://www.vgxit.com

本博客对应视频教程:http://www.vgxit.com/course/23


Spring Aop基于AspectJ开发


1,选择切点

Spring是一个方法级别的AOP框架。也就是我们可以再调用某个方法之前,之后,正常返回之后,异常返回之后来切入我们的代码。我们需要被拦截的方法就叫做一个切点。那么我们应该创建对应的切点。这里我们就直接把上节课讲的添加用户复制过来作为我们的切点。

1,创建对应的PO:

package com.vgxit.learn.spring.ktdm.springaop.po;

import lombok.Data;

@Data
public class User {
    private Integer id;
    private String name;
    private Short gender;
}

2,创建对应的切点:

package com.vgxit.learn.spring.ktdm.springaop.service;

import com.vgxit.learn.spring.ktdm.springaop.po.User;

public interface IUserService {
    void add(User user);
}
package com.vgxit.learn.spring.ktdm.springaop.service.impl;

import com.vgxit.learn.spring.ktdm.springaop.po.User;
import com.vgxit.learn.spring.ktdm.springaop.service.IUserService;

public class UserService implements IUserService {
    @Override
    public void add(User user) {
        System.out.println("添加用户[" + user + "]到数据库");
        throw new RuntimeException("添加错误");
    }
}

2,创建切面

选择好了切点之后,我们就可以创建切面了。切面就如同我们上节课写的拦截器。在spring中,我们只需要提供一个AspectJ注解,就可以让一个类成一个切面。但是如果我们想要使用这个注解,必须引入对应的依赖包:

<dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.6</version>
            </dependency>

接下来我们创建对应的切面:

package com.vgxit.learn.spring.ktdm.springaop.aspect;

import org.aspectj.lang.annotation.*;

@Aspect//使用了这个注解就表明该类为一个切面类
public class TranAspect {
    @Before("execution(* com.vgxit.learn.spring.ktdm.springaop.service.impl.UserService.add(..))")
    public void before() {
        System.out.println("获取数据库连接");
        System.out.println("开启事务");
    }

    @After("execution(* com.vgxit.learn.spring.ktdm.springaop.service.impl.UserService.add(..))")
    public void after() {
        System.out.println("对应逻辑执行完成");
    }

    @AfterReturning("execution(* com.vgxit.learn.spring.ktdm.springaop.service.impl.UserService.add(..))")
    public void afterReturning() {
        System.out.println("提交事物");
    }

    @AfterThrowing("execution(* com.vgxit.learn.spring.ktdm.springaop.service.impl.UserService.add(..))")
    public void afterThrowing() {
        System.out.println("事物回滚");
    }
}

上面我们使用了Aspect来定义对应的类是一个切面。然后我们使用了4个注解来定义对应的方法。这四个注解的含义如下:

  1. @Before:在切点调用之前前置通知执行的方法。
  2. @After:在切点调用之后后置通知执行的方法。
  3. @AfterReturning:在被代理对象的方法正常返回之后调用
  4. @AfterThrowing:在被代理对象的方法抛出异常之后调用

3,连接点

连接点在AOP中的作用其实就是用来判断是否要拦截对应的方法。比如我们上面的4个注解我们就可以理解成为连接点。

比如我们的@After("execution(* com.vgxit.learn.spring.ktdm.springaop.service.impl.UserService.add(..))"):

  • execution:代表执行方法的时候触发
  • *:代表方法可以是任意返回类型
  • com.vgxit.learn.spring.ktdm.springaop.service.impl.UserService表示对应的方法提供者的全限定名
  • add:表示被拦截的方法的名称
  • (..):表示是任意类型的参数

4,测试运行

1,首先应该创建一个配置类

package com.vgxit.learn.spring.ktdm.springaop.config;

import com.vgxit.learn.spring.ktdm.springaop.aspect.TranAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@ComponentScan("com.vgxit.learn.spring.ktdm.springaop")
@EnableAspectJAutoProxy//表示spring启动AspectJ框架自动代理
@Configuration
public class SpringAopConfig {
    //注入切面
    @Bean
    public TranAspect tranAspect() {
        return new TranAspect();
    }
}

2,测试:

package com.vgxit.learn.spring.ktdm.springaop.test;

import com.vgxit.learn.spring.ktdm.springaop.config.SpringAopConfig;
import com.vgxit.learn.spring.ktdm.springaop.po.User;
import com.vgxit.learn.spring.ktdm.springaop.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringaopTest001 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringAopConfig.class);
        IUserService userService = ctx.getBean(IUserService.class);
        User user = User.builder().id(1).name("李一桐").gender((short) 2).build();
        userService.add(user);
    }
}

5,简化连接点操作

我们上面写的这个切面是比较复杂的,每一个连接点我们都把自己的配置重复写了一遍,其实这个完全没有,我们可以简化。

package com.vgxit.learn.spring.ktdm.springaop.aspect;

import org.aspectj.lang.annotation.*;

@Aspect//使用了这个注解就表明该类为一个切面类
public class TranAspect {
    @Pointcut("execution(* com.vgxit.learn.spring.ktdm.springaop.service.impl.UserService.add(..))")
    public void tranPointer(){}

    @Before("tranPointer()")
    public void before() {
        System.out.println("获取数据库连接");
        System.out.println("开启事务");
    }

    @After("tranPointer()")
    public void after() {
        System.out.println("对应逻辑执行完成");
    }

    @AfterReturning("tranPointer()")
    public void afterReturning() {
        System.out.println("提交事物");
    }

    @AfterThrowing("tranPointer()")
    public void afterThrowing() {
        System.out.println("事物回滚");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

V哥学It

赏小的一个钱吧

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

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

打赏作者

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

抵扣说明:

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

余额充值