• Spring学习笔记04-AOP(一)


    一、AOP的使用(步骤分析)

    1、加入jar包

    2、在配置文件中加入aop的命名空间

    3、基于注解的方式

    ① 在配置文件中加入如下配置

    ② 把横切关注点的代码抽象到切面的类中

    a、切面首先是一个 IOC 中的 bean,即加入@Component 注解

    b、切面还需要加入@Aspect 注解

    ③ 在类中声明各种通知

    a、声明一个方法

    b、在方法前加入各方法的注解,如:@Before

    ④ 可以在通知方法中声明一个类型为JoinPoint的参数,然后就能访问链接细节,如方法名称和参数值。

    二、实例代码

    package aop;
    
    public interface Yunsuan {
        
        int add(int i,int j);
        int sub(int i,int j);
        int mul(int i,int j);
        int div(int i,int j);
    
    }
    Yunsuan.java
    package aop;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class YunsuanImpl implements Yunsuan {
    
        @Override
        public int add(int i, int j) {
            //System.out.println("begin"+i+","+j);
            int result=i+j;
            //System.out.println("end"+result);
            return result;
        }
    
        @Override
        public int sub(int i, int j) {
            //System.out.println("begin"+i+","+j);
            int result=i-j;
            //System.out.println("end"+result);
            return result;
        }
    
        @Override
        public int mul(int i, int j) {
            //System.out.println("begin"+i+","+j);
            int result=i*j;
            //System.out.println("end"+result);
            return result;
        }
    
        @Override
        public int div(int i, int j) {
            //System.out.println("begin"+i+","+j);
            int result=i/j;
            //System.out.println("end"+result);
            return result;
        }
    
    }
    YunsuanImpl.java
    package aop;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
    
        public static void main(String[] args) {
            ApplicationContext c=new ClassPathXmlApplicationContext("aop.xml");
            Yunsuan yunsuan=c.getBean(Yunsuan.class);
            int result=yunsuan.add(3, 4);
            System.out.println("result="+result);
            int re=yunsuan.div(3, 4);
            System.out.println("result="+re);
        }
    }
    Main.java
    <?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:aop="http://www.springframework.org/schema/aop"
        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/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    
        <!-- 配置自动扫描的包 -->
        <context:component-scan base-package="aop"></context:component-scan>
    
        <!--使AspjectJ注解起作用:自动为匹配的类生成代理对象 -->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
    
    </beans>
    aop.xml
    package aop;
    
    import java.util.Arrays;
    import java.util.List;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    //把这个类声明为一个切面,放到IOC容器,再声明为一个切面
    @Aspect
    @Component
    public class Qiemian {
    
        //声明该方法是一个前置通知
        //@Before("execution(public int aop.Yunsuan.*(int,int))")
        //@Before("execution(* aop.*.*(int,int))")
        @Before("execution(* aop.*.*(..))")
        public void before(JoinPoint joinpoint) {
            String name=joinpoint.getSignature().getName();
            List<Object> args=Arrays.asList(joinpoint.getArgs());
             System.out.println(name+" begin "+args);
        }
        
        //后置通知,目标方法执行后(无论异常)
        @After("execution(* aop.*.*(..))")
        public void after(JoinPoint joinpoint) {
            String name=joinpoint.getSignature().getName();
            //不能返回目标方法执行的结果
            //List<Object> args=Arrays.asList(joinpoint.getArgs());
             System.out.println(name+" end ");
        }
        
        //返回通知,在方法正常结束后执行,,可以访问到方法的返回值
        @AfterReturning(value="execution(* aop.*.*(..))",
                returning="result")
        public void afterReturning(JoinPoint joinpoint,Object result) {
            String name=joinpoint.getSignature().getName();
            System.out.println(name+" end with " + result);
        }
        
        //异常通知,在方法出现异常时执行,可以访问到异常对象
        @AfterThrowing(value="execution(* aop.*.*(..))",
                throwing="e")
        public void afterThrowing(JoinPoint joinpoint,Exception e) {
            String name=joinpoint.getSignature().getName();
            System.out.println(name+" exception " + e);
        }
        
        //环绕通知,需携带ProceedingJoinPoint类型的参数,必须有返回值
        @Around("execution(* aop.*.*(..))")
        public Object around(ProceedingJoinPoint pdj) {
            Object result=null;
            String name=pdj.getSignature().getName();
            //执行目标方法
            try {
                //前置通知
                System.out.println(name+" begin with " + Arrays.asList(pdj.getArgs()));
                result = pdj.proceed();
                //后置通知
                System.out.println(name+" end with " + Arrays.asList(pdj.getArgs()));
            } catch (Throwable e) {
                // TODO 自动生成的 catch 块
                //异常通知
                System.out.println(name+" exception " + e);
                throw new RuntimeException(e);
            }
            //后置通知
            System.out.println(name+" end ");
            return result;
        }
    }
    Qiemian.java

     

  • 相关阅读:
    C++ 类 构造函数 constructor
    数据库——关系代数
    海明码
    C++ this指针
    C++ 类的定义与实现
    C++ 函数 内联函数
    C++ 函数 函数的重载 有默认参数的函数
    2017年第八届蓝桥杯【C++省赛B组】
    2018年第九届蓝桥杯【C++省赛B组】
    C++ 函数 参数传递方式
  • 原文地址:https://www.cnblogs.com/MoooJL/p/12663408.html
Copyright © 2020-2023  润新知