AOP

AOP

AOP:Aspect Oriented Programming面向切面编程

AOP的优点:

  • 降低模块之间的耦合度

  • 使系统更容易扩展

  • 更好的代码复用

  • 非业务代码更加集中,便于统一管理

  • 业务代码更简洁,不掺杂其他代码影响

    AOP是面向对象编程的一个补充,在运行时,动态的将代码切入到指定方法,指定位置上的编程思想就是面向切面编程。

    将不同方法的同一位置抽象成一个切面对象,对该对象进行编程就是AOP

如何使用?

  • 创建maven工程,pom.xml中添加AOP依赖

    <!--添加AOP依赖-->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-aop</artifactId>
           <version>5.0.11.RELEASE</version>
       </dependency>
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-aspects</artifactId>
           <version>5.0.11.RELEASE</version>
       </dependency>
    • 创建一个计算机接口Cal,定义四个方法。

      public interface Cal {
         public  int add(int num1,int num2);
         public  int sub(int num1,int num2);
         public  int mul(int num1,int num2);
         public  int div(int num1,int num2);

      }
package com.southwind.utils.Impl;

import com.southwind.utils.Cal;

public class CalImpl implements Cal {
   @Override
   public int add(int num1, int num2) {
       //打印日志信息
       System.out.println("add方法的参数是["+num1+","+num2+"]");
       int result = num1+num2;
       System.out.println("add方法的结果是"+result);
       return result;
  }

   @Override
   public int sub(int num1, int num2) {
       System.out.println("sub方法的参数是["+num1+","+num2+"]");
       int result = num1-num2;
       System.out.println("sub方法的结果是"+result);
       return result;
  }

   @Override
   public int mul(int num1, int num2) {
       System.out.println("mul方法的参数是["+num1+","+num2+"]");
       int result = num1*num2;
       System.out.println("mul方法的结果是"+result);
       return result;
  }

   @Override
   public int div(int num1, int num2) {
       System.out.println("div方法的参数是["+num1+","+num2+"]");
       int result = num1/num2;
       System.out.println("div方法的结果是"+result);
       return result;
  }
}

 

上述代码中,日志信息和业务逻辑的耦合性很高,不利于系统的维护,可以用AOP进行优化。

如何实现AOP?

  • 使用动态代理方式实现AOP

  • 给业务代码找一个代理,打印日志信息由代理完成,业务代码只需关心自身的业务。

  •  

  • package com.southwind.aop;

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;

    import java.util.Arrays;
    //注解aspect成为一个切面对象
    @Aspect
    //注解Component交给ioc管理。
    @Component
    public class LoggerAspect {
       //before代表切面的时机,在方法执行之前切面。括号内表示切面的方法,CalImpl类里面的所有日志方法都是要切面的。)
       //*方法通配符,(..)参数通配符。

       @Before("execution(public int soutchwind.utils.impl.CalImpl.*(..)")
    public  void before(JoinPoint joinPoint){//joinpoint连接点
         //获取方法名
           String name =joinPoint.getSignature().getName();
         //获取参数
           String args = Arrays.toString(joinPoint.getArgs());
           System.out.println(name+"方法的参数是:"+args);

      }
    }

LoggerAspect类定义处添加的两个注解

  • @Aspect:表示该类是切面类。

  • @Component:将该类的对象注入到Ioc容器中。

  • @before表示方法执行的具体位置和时机

    CalImpl也需要添加@Component,交给IoC容器处理。

spring.xml配置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"
      xmlns:p="http://www.springframework.org/schema/p" 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">
<!--自动扫描-->
<!--扫描指定包里的所有类,查找这些类中是否有带有@Component注解,并把带有这些注解的类交给ioc-->
<context:component-scan base-package="com.southwind"></context:component-scan>
<!--使aspect注解生效,为目标类自动生成代理对象-->
   <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

context:component-scan 将com.southwind包中的所有类进行扫描,如果类同时添加了@Component,则将该类扫描到ioc容器中,即Ioc管理它的对象。

aop:aspectj-autoproxy让spring框架结合切面类和目标类自动生成动态代理对象.

 

posted on 2023-02-09 13:28  张铁蛋666  阅读(73)  评论(0编辑  收藏  举报

导航