zoukankan      html  css  js  c++  java
  • 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();
        }
    }
    
    作者:蓝月

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

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

  • 相关阅读:
    hdu-1698(线段树,区间修改)
    hdu-1394(线段树)
    hdu-1166(线段树)
    hdu-1251(string+map)
    hdu-1711(kmp算法)
    hdu-2191(完全背包+二进制优化模板)
    hdu-2844(完全背包+二进制优化模板)
    hdu-1171(多重背包+二进制优化)
    SpringMVC 参数中接收数组、List写法
    如何高效的查询数组中是否包含某个值
  • 原文地址:https://www.cnblogs.com/viplanyue/p/13573743.html
Copyright © 2011-2022 走看看