Java第四十天,Spring框架系列,基于注解的AOP

一、注解详解

  • @Aspect ===> 表示当前类为切面类
  • @Pointcut ===> 切入点表达式
  • @Before ===> 前置通知
  • @AfterReturning ===> 后置通知
  • @AfterThrowing ===> 异常通知
  • @After ===> 最终通知
  • @Around ===> 环绕通知

注意:

1.注解中切入点表达式的配置方法和XML配置方法一直

2.五种通知可以自定义切入点表达式,也可以引用被注解 @Pointcut  标注的切入点表达式;引用时写被注解 @Pointcut  标注的方法名及其括号

二、配置步骤

1.在bean.xml配置文件中导入相关约束,可参考

spring-framework-5.0.2/spring-framework-5.0.2.RELEASE-docs/spring-framework-reference/core.html#spring-core

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">


</beans>

2.在bean.xml配置文件中添加要扫描的包

<!--配置spring创建容器时要扫描的包-->
<context:component-scan base-package="com.huhai"></context:component-scan>

3.在bean.xml配置文件中添加以下内容,以开启spring对注解AOP的支持

<!--配置spring开启注解AOP的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

5.在业务层代码中添加注解 @Service 交由spring容器管理

6.在增强类中添加注解 @Component,因为增强类不属于三层结构, 所以用@Component注解将该类交由Spring容器来管理

7.在增强类的增强方法中添加指定类型的通知注解,并写好切入点表达式

三、示例项目

1.项目整体框架

2.业务层接口

package com.huhai;

public interface IAccountService {
    void saveAccount();
    void updateAccount(int i);
    int deleteAccount();
}

3.业务层接口实现类

package com.huhai.impl;

import com.huhai.IAccountService;
import org.springframework.stereotype.Service;

@Service(value = "accountServiceImpl")
public class AccountServiceImpl implements IAccountService {

    public void saveAccount() {
        System.out.println("账户成功保存");
    }

    public void updateAccount(int i) {
        System.out.println("账户成功更新");
    }

    public int deleteAccount() {
        System.out.println("账户成功删除");
        return 0;
    }
}

4.增强类(通知类)

package com.huhai.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

//因为该类不属于三层结构, 所以用@Component注解将该类交由Spring容器来管理
@Component(value = "logger")
//添加Aspect注解,表示当前类为切面类
@Aspect
public class Logger {
    //让其在切入点方法执行之前执行(切入点方法就是业务层方法) 前置通知
    @Before("stand()")
    public void beforeLog(){
        System.out.println("账户保存前数据备份成功");
    }

    //让其在切入点方法执行之后执行 最终通知
    @After("stand()")
    public void afterLog(){
        System.out.println("账户提交后数据校验成功");
    }

    //让其在切入点方法执行发生异常之后执行 异常通知
    @AfterThrowing("stand()")
    public void exceptionLog(){
        System.out.println("账户保存过程中出现了异常");
    }

    //让其在切入点方法执行成功返回之后执行 后置通知
    @AfterReturning("stand()")
    public void returnLog(){
        System.out.println("账户保存后数据已提交完成");
    }

    //替换被增强的切入点方法 环绕通知
    //利用环绕通知可以实现以上四种通知
    @Around("stand()")
    public Object aroundLog(ProceedingJoinPoint pjp){

        Object result = null;
        System.out.println("环绕通知——————前置通知");
        //得到方法执行所需的参数
        Object[] args = pjp.getArgs();
        try {
            //明确调用业务层方法;否则环绕通知将不会执行业务层方法
            result = pjp.proceed(args);
            System.out.println("环绕通知——————后置通知");
        } catch (Throwable throwable) {
            System.out.println("环绕通知——————异常通知");
            throwable.printStackTrace();
        }finally {
            System.out.println("环绕通知——————最终通知");
            return result;
        }
    }

    public void allBefore(){
        System.out.println("通配符通知已执行");
    }

    //切入点表达式
    @Pointcut(value = ("execution(* com.huhai.impl.*.*(..))"))
    public void stand(){ }
}

5.bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--配置spring创建容器时要扫描的包-->
    <context:component-scan base-package="com.huhai"></context:component-scan>

    <!--配置spring开启注解AOP的支持-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

6.pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.huhai</groupId>
    <artifactId>demo20</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--设置打包方式-->
    <packaging>jar</packaging>

    <!--导入spring坐标-->
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

        <!--解析切入点表达式-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.0</version>
        </dependency>
    </dependencies>


</project>

7.表现层

package com.huhai.ui;

import com.huhai.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Realize {
    public static void main(String[] args) {
        //获取容器
        ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
        //获取Bean对象
        IAccountService accountService = (IAccountService) app.getBean("accountServiceImpl");
        accountService.saveAccount();
        accountService.updateAccount(1);
        accountService.deleteAccount();
    }
}
作者:蓝月

-------------------------------------------

个性签名:能我之人何其多,戒骄戒躁,脚踏实地地走好每一步

原文地址:https://www.cnblogs.com/viplanyue/p/13573743.html