Spring中如何实现Aop效果呢?

戚薇 Spring 发布时间:2023-05-13 09:41:12 阅读数:16169 1
下文笔者讲述Spring中实现AOP切面的方法及示例分享,如下所示

AOP简介

AOP(Aspect Orient Programming):面向切面编程
  AOP是一种编程思想
     是面向对象编程(OOP)的补充
  面向对象编程将程序抽象成各个层次的对象
而面向切面编程是将程序抽象成各个切面
  面向切面编程是Spring核心思想之一

Spring中如何实现AOP

Spring中aop是通过动态代理实现

Spring通过一个切面类
  当在类上加入@Aspect注解
  定义一个Pointcut方法
   最后定义一系列的增强方法
采用以上的步骤即可实现对一个对象的切面操作

使用注解实现Spring AOP

定义Spring AOP通知类型


@Before:
  前置通知
  在目标方法执行之前运行的通知
  但不能阻止执行流继续到连接点(除非抛出异常)
@AfterReturning
  返回后通知
   在目标方法正常返回之后运行的通知(即一个方法正常返回而且没有抛出异常)
@AfterThrowing:
   抛出异常后通知
   在目标方法通过抛出异常退出
    则运行AfterThrowing通知
@After:
  后置通知
  在目标方法运行结束之后
   不管目标是否正常退出或者异常返回都将运行的通知
@Around:
   环绕通知
   环绕目标方法的通知
   环绕通知可以在方法调用之前和之后执行自定义行为

定义AOP增强点

@Aspect:作用是把当前类标识为一个切面供容器读取
@Pointcut:切入点,可以定义表达式或者方法签名
@EnableAspectJAutoProxy:用于开启Spring Aop注解的功能

AOP的示例

service接口类

public interface TestService {
    void test();
}

实现类

@Service
public class TestServiceImpl implements TestService {
    @Override
    public void test() {
        System.out.println("TestService的Test()方法执行");
    }
}

创建Controller

 
@Component("TestController")
public class TestController {

    @Autowired
    private TestService testService;

    public void Test(){
        testService.test();
    }
}
 

定义一个切面类并且注册到ioc容器中

切入点表达式看你项目实现类的package

//切面类
@Aspect
@Component
public class TestAspect {

    //定义切入点
    @Pointcut("execution(* com.example.springaop.service.impl..*.*(..))")
    private void pointcut(){

    }

    //环绕通知
    @Around("pointcut()")
    //ProceedingJoinPoint 连接点对象
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Exception {
        //获取签名
        Signature signature = proceedingJoinPoint.getSignature();
        //获取目标方法名称
        String methodName = signature.getName();
        System.out.println("开始执行环绕通知,方法名称"+ methodName);
        try{
            long startTime = System.currentTimeMillis();
            //执行实现类test方法
            Object proceed = proceedingJoinPoint.proceed();
            long endTime = System.currentTimeMillis();
            System.out.println(methodName + "方法耗时:" + (endTime - startTime) + "毫秒");
            return proceed;
        }catch (Throwable throwable){
            throwable.printStackTrace();
            throw new Exception("方法异常");
        }
    }


    //前置通知
    @Before("pointcut()")
    public void before(JoinPoint joinpoint){
        String methodName = joinpoint.getSignature().getName();
        System.out.println("开始执行前置通知,方法名称"+ methodName);
    }

    //后置通知
    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("开始执行后置通知,方法名称"+ methodName);
    }

    //返回通知
    @AfterReturning("pointcut()")
    public void afterReturning(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("开始执行后置返回通知,方法名称"+ methodName);
    }

    //异常通知
    @AfterThrowing("pointcut()")
    public void afterThrowing(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("开始执行抛出异常返回通知,方法名称"+ methodName);
    }

}

定义一个aop config配置类

@Configuration
//开启Aop注解
@EnableAspectJAutoProxy
@ComponentScan("com.example.springaop")
public class AopConfig {
}
 

测试运行

@Test
void contextLoads() {
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
    TestController testController = (TestController) annotationConfigApplicationContext.getBean("TestController");
    testController.Test();
}
 
AOP运行后效果
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/Spring/202305/6429.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者