• Spring/AOP框架, 以及使用注解


    1, 使用代理增加日志, 也是基于最原始的办法

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class LoggingProxy {
        /*
         * 代理类, 基于接口
         */
        //要被代理的对象, 目标对象
        private Icalculator target;
        //生成一个构造方法
        public LoggingProxy(Icalculator target) {
            super();
            this.target = target;
        }
        //应用通知. 并产生对象
        public Icalculator getProxy() {
            Icalculator ica = null;
            //应用通知
            //获得类加载器: ClassLoader, 类加载器在getClass()方法里面
            ClassLoader cl = target.getClass().getClassLoader();
            
            //获得class中所有方法的数组, 数组的内容一定要是接口.class
            Class[] cla= new Class[] {Icalculator.class};
            //Class[] al = new Class[] {IJiSuanQi.class};//接口
            
            //获得
            InvocationHandler ih = new InvocationHandler() {
                @Override
                //调用invoke的时候就是实现一个切面编程
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //在这之前可以增加数据验证
                    Object obj = null;
                    System.out.println(method.getName()+" 开始调用");
                    try {
                        obj = method.invoke(target, args);
                    }
                    catch(Exception e) {
                        System.out.println("异常通知: "+method.getName());
                    }
                    System.out.println(method.getName()+" 结束调用");
                    return obj;
                }
            };
            //产生代理对象, 引用了反射的jar包
            ica = (Icalculator)Proxy.newProxyInstance(cl, cla, ih);
            return ica;
        }
    }

    2, 使用AOP框架

    配置文件

        <!-- 前面定义的类class -->
        <bean id="cal" class="com.hanqi.Calculator">
        </bean>
        
        <!-- 切面类 -->
        <bean id="la" class="com.hanqi.LoggingAspect">
        </bean>
        
        <!-- 定义AOP -->
        <aop:config>
        <!-- 配置切点表达式, 被切入的方法 -->
        <!-- expression写对象必须是个接口被切入方法的名字, 如果要写所有的方法就用*号表示 -->
            <aop:pointcut expression="execution(* com.hanqi.Icalculator.*(int,int))" id="loggingpointcut"/>
            
            <!-- 配置切面和通知 -->
            <aop:aspect ref="la">
                <!-- 方法前通知 -->
                <aop:before method="beforeMethod" pointcut-ref="loggingpointcut"/>
                <aop:after method="afterMethod" pointcut="execution(* com.hanqi.Icalculator.cheng(int,int))"/>
                <aop:after-throwing method="exceptionMethod" pointcut-ref="loggingpointcut" throwing="ex"/>
                <aop:after-returning method="returnMethod" pointcut-ref="loggingpointcut" returning="obj"/>
            </aop:aspect>
            
        </aop:config>

    定义切面类

    import java.util.Arrays;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    public class LoggingAspect {
        //切面类, 前置通知
        public void beforeMethod(JoinPoint jp) {
            //获取方法名
            String str = jp.getSignature().getName();
            //返回一个参数列表
            Object[] obj = jp.getArgs();
            System.out.println("方法名 = "+str);
            System.out.println(Arrays.asList(obj));
            System.out.println("这里是方法前的通知");
        }
        public void afterMethod(JoinPoint jp) {
            System.out.println("这里是方法后的通知");
        }
        //异常通知
        public void exceptionMethod(JoinPoint jp,Exception ex) {
            System.out.println("异常信息"+ex);
        }
        
        //返回通知
        public void returnMethod(JoinPoint jp,Object obj) {
            System.out.println("返回通知的结果: "+obj);
        }
    }

    3, 使用注解的方式(标红的部分是注解), 一定记得写上返回值和, expression表达式

    import org.springframework.stereotype.Component;
    
    @Component("cal")
    public class Calculator implements Icalculator {
        ......
        方法体
        ......
    }
    import java.util.Arrays;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LoggingAspect {
        //切面类, 前置通知
        @Before(value = "execution(* com.hanqi.Calculator.*(..))")
        public void beforeMethod(JoinPoint jp) {
            //获取方法名
            String str = jp.getSignature().getName();
            //返回一个参数列表
            Object[] obj = jp.getArgs();
            System.out.println("方法名 = "+str);
            System.out.println(Arrays.asList(obj));
            System.out.println("这里是方法前的通知");
        }
        //后置通知
        @After("execution(* com.hanqi.Calculator.*(..))")
        public void afterMethod(JoinPoint jp) {
            System.out.println("这里是方法后的通知");
        }
        //异常通知
        @AfterThrowing(pointcut="execution(* com.hanqi.Calculator.*(..))", throwing="ex")
        public void exceptionMethod(JoinPoint jp,Exception ex) {
            System.out.println("异常信息"+ex);
        }
        
        //返回通知
        @AfterReturning(pointcut="execution(* com.hanqi.Calculator.*(..))", returning="obj")
        public void returnMethod(JoinPoint jp,Object obj) {
            System.out.println("返回通知的结果: "+obj);
        }
    }

     注解的配置文件

    <?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/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
            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-4.2.xsd">
    
    <!-- 使用注解的方式 -->
    <!-- 扫描器 -->
    <context:component-scan base-package="com.hanqi"></context:component-scan>
    <!-- 启用AOP注解 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    </beans>
  • 相关阅读:
    数据库基础——EXISTS和IN
    C#基础——加密
    C#基础——派生和继承
    SQL Server——报表服务
    SQL Server——SQL Server Profiler
    UML基础——UML简介和历史
    C#基础——密码加密
    C#(ASP.NET)错误: 无法获取属性“0”的值: 对象为 null 或未定义 关键字 'user' 附近有语法错误。
    SQL Server——存储过程
    链表的声明及操作
  • 原文地址:https://www.cnblogs.com/wgbs25673578/p/5164849.html
Copyright © 2020-2023  润新知