spring---AOP---学习记录---21.05.10

21.05.10

什么是AOP

AOP(Aspect-Oriented Programming,面向切面编程)是对传统传统 OOP(Object-Oriented Programming,面向对象编程)的补充,属于一种横向扩展。其将与核心业务无关的代码,如日志记录、性能监控、事务处理等从业务逻辑代码中抽离出来,进行横向排列,从而实现低耦合,提高开发效率。

怎样理解面向切面编程

使用aop的目的:是个已经存在的一些类和方法,增加额外的功能,前提是不改变原来类的代码

1)需要在分析项目功能时,找出切面
2)合理的安排切面的执行时间(在目标方法前,还是目标方法后)
3)合理的安放切面执行的位置,在哪个类,哪个方法增加增强功能

术语

1)Aspect:切面,表示增强的功能,就是一堆代码,完成某个一个功能。给业务功能,常见的切面功能有日志,事务,统计信息,参数检查,权限验证
2)JoinPoint:连接点,连接业务方法和切面的位置,就某类中的业务方法
3)Pointcut:切入点,指多个连接点方法的集合。多个方法
4)目标对象:给哪个类增加功能,哪个就是目标对象
5)Advice:通知,通知表示切面功能执行的时间

一个切面的三个关键的要素

1)切面的功能代码,切面干什么
2)切面的执行位置,使用Pointcut表示切面执行的位置
3)切面的执行时间,使用Advice表示时间,在目标方法之前,还是目标方法之后

aop的实现

aop是一个规范,是动态的一个规范化,一个标准
sop的技术实现框架:
1.spring:spring在内部实现了aop规范,能做aop的工作
spring主要在事务处理时使用aop
我们项目开发中很少使用spring的aop实现(笨重)

2.aspectJ:一个开源的专门做aop的框架,spring框架中集成了aspectJ框架,通过spring就能使用aspectj的功能。
aspectj框架事项aop的两种方式:
1)使用xml的配置文件:配置全局事务
2)使用注解,我们在项目中要做aop功能,一般都是用注解,aspectj有5个注解
@Before @AfterReturning @Around @AfterThrowing @After

AsjpectJ的切入点给表达式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用aspectj实现aop的基本步骤:

1.新建maven项目
2.加入依赖
1)spring依赖
2)aspectj依赖
3)junit单元测试
3.创建目标类:接口和他的实现类。要做的是给类中的方法增加功能
4.创建切面类:普通类
1)在类的上面加入@Aspect
2)在类中定义方法,方法就是切面要执行的功能代码
5.创建spring的配置文件:声明对象,把对象交给容器统一管理
声明对象可以使用注解或者xml配置文件 < bean >
1)声明目标对象
2)声明切面类对象
3)声明aspectj框架中的自动代理生成器标签
自动代理生成器:用来完成代理对象的自动创建功能的
6.创建测试类,从spring容器中获取目标对象(实际就是代理对象)
通过代理执行方法,实现aop的功能增强

    <!--aspectj依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.3.1</version>
    </dependency>

@Aspect

aspect框架中的注解
作用:表示当前类是切面类
切面类:是用来个业务方法增加功能的类,在这个类中有切面的功能代码
位置:在类定义的上面

/*
* 定义方法,方法是事项切面功能的。
* 方法定义要求:
* 1.公共方法public
* 2.方法没有返回值
* 3.方法名称自定义
* 4.方法可以有参数,也可以没有参数
* 如果有参数,参数不是自定义的,有几个参数类型可以使用
*/

SomeService.java

package com.node.ba01;

public interface SomeService {
    void doSome(String name,Integer age);
}

SomeServiceImpl.java

package com.node.ba01;

public class SomeServiceImpl implements SomeService {
    @Override
    public void doSome(String name,Integer age) {

        //给doSome方法增加一个功能,在doSome()执行之前,输出方法的执行时间
        System.out.println("===目标方法doSome===");
    }
}

MyAspect.java

package com.node.ba01;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import java.util.Date;

@Aspect
public class MyAspect {
    
    @Before(value="execution(public void com.node.ba01.SomeServiceImpl.doSome(String,Integer))")
    public void myBefore(){
        //就是你切面要执行的功能代码
        System.out.println("切面功能:在目标方法之前输出执行时间:"+ new Date());
    }


}

applicationContext.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 https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--把对象交给spring容器,由spring容器统一创建,管理对象-->
    <!--声明目标对象-->
    <bean id="someService" class="com.node.ba01.SomeServiceImpl"/>

    <!--声明切面类对象-->
    <bean id="myAspect" class="com.node.ba01.MyAspect" />

    <!--声明自动代理生成器-->
    <!--使用aspectj框架内部的功能,创建目标对象的代理对象
        创建代理对象是在内存中实现的,修改目标对象的内存中的结构。创建为代理对象,
        所以目标对象就是被修改后的代理对象

        aspectj-autoproxy:会把spring容器中的所有目标对象,一次性都生成代理对象
     -->
    <aop:aspectj-autoproxy />


</beans>

测试代码

package com.node;

import com.node.ba01.SomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest01 {

    @Test
    public void test01(){

        String config="applicationContext.xml";
        ApplicationContext ac=new ClassPathXmlApplicationContext(config);
        //从容器中获取目标对象
        SomeService proxy= (SomeService) ac.getBean("someService");
        //通过代理的对象执行方法,事项目标方法执行时,增强了功能
        proxy.doSome("lisi",20);
        //com.sun.proxy.$Proxy6:jdk动态代理
        System.out.println(proxy.getClass().getName());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值