zoukankan      html  css  js  c++  java
  • Spring AOP的使用实例

    Spring AOP可以实现对指定的类的公共方法进行拦截,添加前置和后置处理,甚至对方法调用进行mock替换。内部实现原理是使用的JAVA的动态代理(针对具有接口的类)或者CGLIB(针对没有接口的类)。

    下面以一个具体的代码例子来演示Spring AOP的使用。

    1. 新建一个idea的maven工程

    pom.xml添加AOP需要的依赖包:

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>5.1.3.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.9.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.1.3.RELEASE</version>
            </dependency>

    2.Spring AOP的配置

    在resources目录下新增applicationContext.xml文件,进行Spring AOP的配置。

    <?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"
           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">
    
        <bean id="userService" class="io.spring2go.corespring.command.aop.UserServiceImpl"></bean>
        <bean id="logAdvisor" class="io.spring2go.corespring.command.aop.LogAdvisor"></bean>
    
        <aop:config>
            <aop:aspect ref="logAdvisor">
                <aop:pointcut expression="execution(* io.spring2go.corespring.command.aop.*.*(..))" id="pointUserService"/>
                <aop:before method="doBefore" pointcut-ref="pointUserService"/>
                <aop:after method="doAfter" pointcut-ref="pointUserService"/>
                <aop:around method="doAround" pointcut-ref="pointUserService"/>
                <aop:after-returning method="doReturn" pointcut-ref="pointUserService"/>
                <aop:after-throwing method="doThrowing" throwing="ex"  pointcut-ref="pointUserService"/>
            </aop:aspect>
        </aop:config>
    </beans>

    3.进行AOP处理的接口和实现类

    接口:

    package io.spring2go.corespring.command.aop;
    
    public interface UserService {
        public String fsindUserById(int id);
    }

    实现类:

    package io.spring2go.corespring.command.aop;
    
    public class UserServiceImpl implements UserService{
    
        @Override
        public String fsindUserById(int id) {
            System.out.println("find user by id["+id+"]....");
            if(id <= 0){
                throw new IllegalArgumentException("user is not exist!");
            }
            return "tom";
        }
    }

    4.AOP代理类

    package io.spring2go.corespring.command.aop;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.Map;
    
    public class LogAdvisor {
    
        /**
         * 在核心业务执行前执行,不能阻止核心业务的调用。
         * @param joinPoint
         */
        public void doBefore(JoinPoint joinPoint){
            System.out.println("-----doBefore().invoke-----");
            System.out.println(" 此处意在执行核心业务逻辑前,做一些安全性的判断等等");
            System.out.println(" 可通过joinPoint来获取所需要的内容");
            System.out.println("-----End of doBefore()------");
        }
    
        /**
         * 手动控制调用核心业务逻辑,以及调用前和调用后的处理,
         *
         * 注意:当核心业务抛异常后,立即退出,转向After Advice
         * 执行完毕After Advice,再转到Throwing Advice
         * @param pjp
         * @return
         * @throws Throwable
         */
        public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("-----doAround().invoke-----");
            System.out.println(" 此处可以做类似于Before Advice的事情");
    
            String targetName = pjp.getTarget().getClass().getName();
            String methodName = pjp.getSignature().getName();
            Object[] arguments = pjp.getArgs();
    
            Class targetClass = Class.forName(targetName);
            Method[] method = targetClass.getMethods();
            Map<String,Object> map = new HashMap<>();
            for (Method m : method) {
                if (m.getName().equals(methodName)) {
                    Class[] tmpCs = m.getParameterTypes();
                }
            }
            //调用核心逻辑
            Object retVal = pjp.proceed();
    
            System.out.println(" 此处可以做类似于After Advice的事情");
            System.out.println("-----End of doAround()------");
            return retVal;
        }
    
        /**
         * 核心业务逻辑退出后(包括正常执行结束和异常退出),执行此Advice
         * @param joinPoint
         */
        public void doAfter(JoinPoint joinPoint) {
            System.out.println("-----doAfter().invoke-----");
            System.out.println(" 此处意在执行核心业务逻辑之后,做一些日志记录操作等等");
            System.out.println(" 可通过joinPoint来获取所需要的内容");
            System.out.println("-----End of doAfter()------");
        }
    
        /**
         * 核心业务逻辑调用正常退出后,不管是否有返回值,正常退出后,均执行此Advice
         * @param joinPoint
         */
        public void doReturn(JoinPoint joinPoint) {
            System.out.println("-----doReturn().invoke-----");
            System.out.println(" 此处可以对返回值做进一步处理");
            System.out.println(" 可通过joinPoint来获取所需要的内容");
            System.out.println("-----End of doReturn()------");
        }
    
        /**
         * 核心业务逻辑调用异常退出后,执行此Advice,处理错误信息
         * @param joinPoint
         * @param ex
         */
        public void doThrowing(JoinPoint joinPoint,Throwable ex) {
            System.out.println("-----doThrowing().invoke-----");
            System.out.println(" 错误信息:"+ex.getMessage());
            System.out.println(" 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等");
            System.out.println(" 可通过joinPoint来获取所需要的内容");
            System.out.println("-----End of doThrowing()------");
        }
    }

    5. 客户端运行

    package io.spring2go.corespring.command.aop;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class TestMain {
    
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = (UserService) ac.getBean("userService");
            userService.fsindUserById(1);
            System.out.println("=============");
    
            try {
                userService.fsindUserById(0);
            } catch (Exception e) {
                System.out.println("异常捕获");
            }
        }
    }
  • 相关阅读:
    muduo 库解析之四:TimeZone
    muduo 库解析之三:Date
    muduo 库解析之九:Condition
    muduo 库解析之八:Mutex
    muduo 库解析之七:Atomic
    [linux]查看文件目录是否为硬链接
    [go] 解决:concurrent write to websocket connection
    [windows] 保存浏览器网页长截图
    [项目] 系统迁移的几个注意点
    [MySQL] order by field 自定义排序
  • 原文地址:https://www.cnblogs.com/windpoplar/p/13269047.html
Copyright © 2011-2022 走看看