Spring AOP简介

AOP简介
  • Aspect Oriented Programming

    • 面向切面编程
  • AOP在Spring中的作用

    • 提供声明式服务(declarative enterprise services),尤其是声明式事务(declarative transaction management)
    • 允许用户实现自定义切面以完善OOP

    AOP is used in the Spring Framework to:
    1.provide declarative enterprise services, especially as a replacement for EJB declarative services. The most important such service is declarative transaction management.
    2.allow users to implement custom aspects, complementing their use of OOP with AOP.

  • AOP编程

    • 在运行时,将代码动态地切入到类的指定方法、指定位置上的编程思想
    • 通过动态代理的方式实现
    • 优点
      • 能够专注于核心业务的处理
      • 减少重复的代码
  • AOP关键概念

    • 关注点
      • concern
      • 一系列的业务,例如: 日志、安全检查
    • 切面
      • aspect
      • 一个关注点的模块化,这个关注点可能会横切多个
    • 连接点
      • join point
      • 程序中方法的执行
    • 通知
      • advice
      • 在切面上某个特定的连接点上执行的动作
      • before advice: 前置通知
      • after returning advice: 后置通知
      • after throwing advice: 异常通知
      • after (finally) advice: 最终通知
      • around advice: 环绕通知
    • 织入
      • weaving
      • 将切面连接到其他应用程序或者对象上,并创建一个通知对象

  • 使用Spring实现AOP
    • 通过Spring的API来实现AOP

      • 配置文件中需要添加aop相关的头文件
      • before advice前置通知的实现

        public class Log implements MethodBeforeAdvice{
            /*
             * @param method being invoked(被调用的方法的方法对象)
             * @param arguments to the method(被调用方法的参数)
             * @param target of the method invocation(被调用方法的目标对象)
             */
            @Override
            public void before(Method method, Object[] args, Object target) throws Throwable {
                System.out.println(target.getClass().getName() + "'s " + method.getName() + 
                        "() is executed");  
            }
        }
      • after returning advice实现

        public class AfterLog implements AfterReturningAdvice{
            /**
             * 目标方法执行后执行的通知
             * @param returnValue: 返回值
             * @param method: 被调用的方法对象
             * @param args: 方法参数
             * @param target: 被调用的方法的目标对象
             **/
            @Override
            public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
                System.out.println(target.getClass().getName() + "'s " + method.getName() + 
                        "has been executed successfully and return value is " + returnValue);
            }
        }
      • 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: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.xsd">
            <bean id="userService" class="com.eric.service.impl.UserServiceImpl"></bean>
            <bean id="log" class="com.eric.log.Log"></bean>
            <bean id="afterLog" class="com.eric.log.AfterLog"></bean> 
            <aop:config>
                <!-- 切入点配置 
                     expression: 表示切入点的执行方法
                     x.y.Class.*(): 表示所有方法都作为切入点
                     x.y.Class.method(..): 表示匹配所有传入参数的格式
                     *用于匹配所有的类/方法
                     ..用于匹配所有的参数格式
                --> 
                <aop:pointcut expression="execution(* com.eric.service.impl.*.*(..))" id="pointcut"/>
                <!-- 配置执行的公共业务
                     advice-ref: 执行的公共业务方法
                     pointcut-ref: 切入点的引用
                 -->
                <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
                <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
            </aop:config>
        </beans>
      • 测试类

        public class Test {
            public static void main(String[] args) {
                ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
                UserService userService = (UserService) ac.getBean("userService");
                userService.add(10);
                userService.delete();       
            }
        }/*output:
        com.eric.service.impl.UserServiceImpl's add() is executed
        add
        com.eric.service.impl.UserServiceImpl's addhas been executed successfully and return value is null
        com.eric.service.impl.UserServiceImpl's delete() is executed
        delete
        com.eric.service.impl.UserServiceImpl's deletehas been executed successfully and return value is null
        */
    • 自定义类实现AOP

      • 切面

        public class Log {
            public void before() {
                System.out.println("execute before method invocation");
            }
            public void after() {
                System.out.println("execute after method invocation");
            }
        }
      • 配置文件

        <bean id="userService" class="com.eric.service.impl.UserServiceImpl"></bean>
            <bean id="log" class="com.eric.log.Log"></bean> 
            <aop:config>
                <!-- 引用切面 -->
                <aop:aspect ref="log">
                    <!-- 配置连接点 -->
                    <aop:pointcut expression="execution(* com.eric.service.impl.*.*(..))" id="pointcut"/>
                    <!-- 配置前置通知 -->
                    <aop:before method="before" pointcut-ref="pointcut"/>
                    <!-- 配置后置通知 -->
                    <aop:after method="after" pointcut-ref="pointcut"/>
                </aop:aspect>
            </aop:config>
    • 使用注解实现AOP

      • 切面

        //表示切面
        @Aspect
        public class Log {
            @Before("execution(* com.eric.service.impl.*.*(..))")
            public void before() {
                System.out.println("execute before method invocation");
            }
            @After("execution(* com.eric.service.impl.*.*(..))")
            public void after() {
                System.out.println("execute after method invocation");
            }
        
            @Around("execution(* com.eric.service.impl.*.*(..))")
            public Object around(ProceedingJoinPoint jp) throws Throwable {
                System.out.println("---around before");
                System.out.println("sign:" + jp.getSignature());
                Object result = jp.proceed();
                System.out.println("---around after");
                return result;
            }
        }
      • 配置文件

        <?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.xsd">
            <bean id="userService" class="com.eric.service.impl.UserServiceImpl"></bean>
            <bean id="log" class="com.eric.log.Log"></bean>
            <aop:aspectj-autoproxy/>
        </beans>

    猜你喜欢

    转载自blog.csdn.net/weixin_40683252/article/details/81136844