aop入门

AOP入门

1.AOP简介

AOP是面向切面编程的意思,全称为Aspect Oriented Programing。他是一种基于OOP之上的一种编程范式,他弥补了OOP的不足,能更好的组织程序结构!

AOP可以把业务的功能步骤做成插拔式的组件(这种开发方式也叫“横向开发”),从而可以用这些组件定制新的功能。因此AOP可以提高业务的复用性,提高开发效率!

2.AOP与OOP的对比

OOP是面向对象编程的意思,以OOP思想指导的程序开发过程就是在建模(类)、创建对象、指挥对象做事情!所以说OOP的开发实际上是根据业务创建模型,基于模型展开业务开发。为了降低程序开发的复杂度,程序开发者们又对OOP下的WEB程序进行了分层设计。

经典的分层设计为:控制层、业务层、持久层。如下图所示:

现在的WEB程序设计基本上都会遵循上面的分层设计原则,每个WEB项目在每个层次的设计过程中或多或少都会有相同的操作步骤或者业务逻辑!也就是说某些项目之间或多或少都有些重复功能的业务代码!这就是项目之间的共性!如果想提高开发效率,就可以将共性功能抽取出来,做成单独的一个组件,各个项目如果要用到这些功能的时候,之间拼接上去就行了!---------这就是AOP要做的事情!

AOP范式编程研究的不是层与层之间的关系,也不是每层内部如何开发,AOP主要关注同一层面的各个不同功能模块之间的共性功能

3.AOP 的底层实现

实际上,AOP 的底层是通过 Spring 提供的的动态代理技术实现的。在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。

AOP 的动态代理技术

  • JDK 代理 : 基于接口的动态代理技术
  • cglib 代理:基于父类的动态代理技术

4.AOP基本概念

  1. 连接点(Joinpoint)(类中所有方法)
  2. 切入点(Pointcut)(确实共性功能代码的方法)
  3. 通知(Advice)(被抽取的共性功能的代码逻辑,通知有位置区分,也就是从切入点方法中被抽取代码的前面还是后面抽象出来的代码,叫通知类型。前置通知、后置通知)
  4. 引入(Introduction)(了解,通知只能抽取逻辑代码,变量是拿不出来的,把变量引入到切入点方法中去,就要用引入)
  5. 目标对象(Target Object):有切入点方法的对象
  6. AOP代理(AOP Proxy):Spring代理目标对象就叫做AOP代理
  7. 织入(Weaving):代理对象把通知织入到目标对象的切入点方法中,是一个动作
  8. 切面(Aspect):通知和切入点之间的关系

连接点(Joinpoint)

程序运行过程中,JVM负责程序运行。执行到某个方法时,JVM能识别当前执行的是哪个方法。这些定义在类中的方法,每个具有独立的功能,在AOP中,将这些具有特定功能的方法称为连接点。

连接点指类中的方法

切入点(Pointcut)

类中的方法具有很多,某些方法具有一些共同的流程,例如数据库连接的获取与关闭,事务的开启与提交,等等。将这些公共的特性抽取出来,抽取完毕后,原始方法中就缺少了这些被抽取的代码。在实际运行时,缺少这些代码是无法完成原始的功能的。这些被抽取了公共功能的方法称为切入点。

切入点指被抽取了共性功能的方法

切入点一定是连接点,连接点不一定是切入点

通知(Advice)

切入点对应的方法的共性功能被抽取后,组成独立代码逻辑,被封装在某个类的某个方法中,在被抽取了共性功能的方法被执行时,这些代码逻辑还要加入原始方法的执行,这些被抽取出来组成独立代码逻辑的共性功能称为通知。

共性功能被抽取后,可能来自于切入点对应的方法中的任何位置,因此通知不仅描述共性的代码逻辑,还是描述被抽取时从何处抽取。例如切入点代码逻辑的前面、中间还是后面,被抽取的代码在切入点中的具体位置,称为通知类别

引入(Introduction)(了解)

通知仅表示切入点被抽取的代码逻辑,对于切入点所在的类,如果存在有共性的成员变量或者成员方法,通知将无法进行描述。AOP提供引入机制,将共性功能的成员进行加入。

引入机制可以为类添加额外的成员变量或者成员方法

引入机制是在编译期或类加载期完成的

目标对象(Target Object)

切入点对应的共性功能被抽取后创建独立的通知完成共性功能,在程序运行时,动态的为类对象执行切入点方法时动态加入被抽取的共性功能,此时需要使用代理的模式完成。此时被代理创建的对象,称为目标对象。

目标对象指包含切入点的类对象

AOP代理(AOP Proxy)

切入点所在的类对象执行切入点方法时,需要将原始的共性功能(通知)加入,此时通过代理的形式创建类对象,并完成共性功能(通知)的加入,上述过程称为AOP代理。

AOP代理的意义是将被抽取共性功能的类对象创建出,同时将共性功能(通知)加入,完成原始的完整操作的执行过程。

切面(Aspect)(在配置文件中配置切面)

切面是一个设计概念,指切入点与通知的匹配模式,换句话说指被抽取了共性功能的方法(切入点)与被抽取了共性功能(通知)对应的绑定关系。

程序设计时,可以设置多个切面,用来描述切入点与通知之间的关系。

织入(Weaving)

通过AOP代理,完成了切入点与通知的融合,并组成了完整的代码逻辑,将通知加入到切入点对应位置的动作称为织入。

织入是一个动态过程,不对应任何代码,可以理解为动态的运行过程。

织入可以在三个阶段进行,编译时,类加载时,运行时。Spring采用的是运行时织入。

5.Spring的AOP实例

导入相关依赖

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.5.RELEASE</version>
</dependency>
<dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
</dependency>

创建目标对象

public class TargetObj {
    public void method1(){
        //System.out.println(1); 共性的功能,把抽取出来的代码做成通知,放在通知类中
        System.out.println(2);
        System.out.println(3);
    }
    public void method2(){
        System.out.println(2);
        System.out.println(3);
    }
}

创建通知类

//通知类:抽取目标对象中共性的代码
public class MyAdvice {
    public void one(){
        System.out.println(1);
    }
}

开启AOP空间的支持(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">
 /beans>

配置AOP的切面

<!--对aop进行配置-->
    <aop:config>
        <!--配置切面-->
        <!--配通知和切入点间的关系-->
        <!--要把通知和切入点所在的类配置成Spring的bean-->
        <aop:aspect ref="advice">
            <!--配置切面,把通知类中的方法和目标对象中的方法关联-->
            <aop:before method="one" pointcut="execution(public void com.lrx.demo.TargetObj.method1())"/>
        </aop:aspect>
    </aop:config>
    <bean id="target" class="com.lrx.demo.TargetObj"></bean>
    <bean id="advice" class="com.lrx.demo.MyAdvice"></bean>

测试

public class AopTest {
    @Test
    public void test1(){
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        TargetObj target = (TargetObj) app.getBean("target");
        target.method1();
        System.out.println("---------------");
        target.method2();
    }
}

6.切入点表达式及通配符

作用:用来匹配切入地方法

格式:**execution(**切入点表达式)

execution([方法的访问控制修饰符] 方法的返回值 包名.类名/接口名.方法名(参数))

注意:方法的访问控制修饰符可以省略,写方法名的时候要把包名和类名全部带上或者正确利用通配符来省略

通配符:*,…(表示任意多个包、参数)

1、 可以匹配返回值类型

2、 可以匹配包名

3、 可以匹配类名

4、 可以匹配方法名

5、 可以匹配参数

7.AOP通知类型

通知类型就是共性代码是在目标对象方法的代码的前面还是后面执行的类型就是通知类型。

类型:位置的意思

AOP的通知类型共5种

1、 before:前置通知(应用:各种校验)

在方法执行前执行

该方法中出现了异常,不会影响前置通知的执行

2、 after:后通知(应用:清理现场)

方法执行完毕后执行,无论方法中是否出现异常都会执行

3、afterReturning:返回后通知(应用:常规数据处理)

方法正常返回后执行,如果方法中抛出异常,无法执行

4、afterThrowing:抛出异常后通知(应用:包装异常信息)

方法抛出异常后执行,如果方法没有抛出异常,无法执行

5、around:环绕通知(应用:十分强大,可以做任何事情)

方法执行前后分别执行,如果方法中有异常,末尾的通知就不执行了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,AOP(面向切面编程)是一种强大的技术,可以在不修改原始代码的情况下增强应用程序的功能。它是一种编程范式,可以将横切关注点(例如日志记录、事务管理、安全性等)从应用程序的主逻辑中分离出来。 以下是在Spring Boot中使用AOP入门步骤: 1. 添加依赖 您需要在pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` 2. 创建一个切面类 您需要创建一个切面类来定义要应用于应用程序的横切关注点。切面类应该使用@Aspect注解进行注释,并且应该包含一个或多个使用@Before、@After、@Around等注解进行注释的通知方法。 例如,以下是一个简单的切面类: ```java @Aspect @Component public class MyAspect { @Before("execution(* com.example.demo.MyService.*(..))") public void beforeAdvice() { System.out.println("Before advice called."); } @After("execution(* com.example.demo.MyService.*(..))") public void afterAdvice() { System.out.println("After advice called."); } } ``` 在上面的示例中,@Before和@After注释用于定义在执行MyService类中的任何方法之前和之后要执行的通知方法。 3. 将切面类注册到Spring Boot应用程序中 您需要将切面类注册到Spring Boot应用程序中,以便它可以在应用程序执行期间应用于横切关注点。您可以使用@Configuration注解或@ComponentScan注解来注册切面类。 例如,以下是使用@Configuration注解注册切面类的示例: ```java @Configuration @EnableAspectJAutoProxy public class AppConfig { @Bean public MyAspect myAspect() { return new MyAspect(); } } ``` 在上面的示例中,@EnableAspectJAutoProxy注解用于启用Spring Boot的自动代理功能,以便Spring Boot可以在运行时创建代理对象。@Bean注解用于将MyAspect类注册为Spring Boot应用程序的bean。 4. 测试切面 一旦您已经注册了切面类并启用了自动代理功能,您可以测试切面是否按预期工作。您可以创建一个MyService类来模拟应用程序的主逻辑,并在其中调用一个或多个方法。 例如,以下是一个简单的MyService类: ```java @Service public class MyService { public void doSomething() { System.out.println("Doing something."); } } ``` 在上面的示例中,MyService类具有一个名为doSomething()的方法,用于模拟应用程序中的主逻辑。 您可以创建一个Spring Boot测试类来测试切面是否按预期工作。例如,以下是一个简单的测试类: ```java @RunWith(SpringRunner.class) @SpringBootTest public class MyServiceTest { @Autowired private MyService myService; @Test public void testDoSomething() { myService.doSomething(); } } ``` 在上面的示例中,@Autowired注解用于将MyService类注入到测试类中。在testDoSomething()方法中,您可以调用MyService类的doSomething()方法,以便切面可以应用于该方法。 如果一切正常,您应该在控制台上看到以下输出: ``` Before advice called. Doing something. After advice called. ``` 这表明切面已成功应用于doSomething()方法,并且切面中定义的通知方法已成功调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值