AOP详解与实例第一章

目录

  • AOP介绍
    • AOP优点
    • AOP使用场景
  • 小试牛刀

AOP介绍

AOP面向切面编程,主要解决特定问题,如:代码重复问题、关注点分离(
水平分离:展示层 ->服务层->持久层
垂直分离:模块划分 订单、库存等模块
切面分离:分离功能性与非功能性需求)

AOP优点

  1. 集中处理某一个关键点/横切逻辑
  2. 可以很方便地添加/删除关注点
  3. 侵入性少,增加代码可读性及可维护性

AOP使用场景

  1. 权限控制
  2. 缓存控制
  3. 事物控制
  4. 日志控制
  5. 性能监控
  6. 分布式追踪
  7. 异常处理

小试牛刀

需求背景产品添加或删除操作只有管理员才可以进行,下面我们就普通实现 VS AOP实现。

新建一个项目

https://start.spring.io/

配置如图
AOP详解与实例第一章_第1张图片
pom.xml添加依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

代码实现结构如下
AOP详解与实例第一章_第2张图片

实体类

package com.demo.aop.entity;

public class Product {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

方便切换用户

package com.demo.aop.security;

/**
 * 方便切换用户
 */
public class CurrentUserHolder {
    private static final ThreadLocal<String> holder = new ThreadLocal<>();

    public static String  get() {
        return holder.get() == null ? "unKnown":holder.get();
    }

    public static void set(String user){
        holder.set(user);
    }
}

权限类,设置你的权限

package com.demo.aop.sevice;

import com.demo.aop.security.CurrentUserHolder;
import org.springframework.stereotype.Component;

@Component
public class AuthService {
    //检查权限
    public void checkAccess(){
        String user = CurrentUserHolder.get();
        if(!"admin".equals(user)){
            throw new RuntimeException("操作不允许!");
        }
    }
}

AOP 注解方式

package com.demo.aop.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AdiminOnly {
}

//------------------------分割线--------------------------------------

package com.demo.aop.security;

import com.demo.aop.sevice.AuthService;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class SecurityAspect {
    @Autowired
    AuthService authService;

    @Pointcut(value = "@annotation(com.demo.aop.annotation.AdiminOnly)")
    public void adminOnly(){}

    @Before("adminOnly()")
    public void check(){
        authService.checkAccess();
    }
}

package com.demo.aop.sevice;

import com.demo.aop.annotation.AdiminOnly;
import com.demo.aop.entity.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 模拟现实场景业务调用
 */
@Service
public class ProductService {
    //传统方法
    @Autowired
    AuthService authService;

    //模拟新增操作 传统方法
    public void insert(Product product){
        authService.checkAccess();
        System.out.println("新增操作成功!");
    }

    //删除造成 AOP 注解方法 只需注解即可
    @AdiminOnly
    public void delete(String id){
        System.out.println("删除操作成功!");
    }
}

演示

package com.demo.aop.sevice;


import com.demo.aop.entity.Product;
import com.demo.aop.security.CurrentUserHolder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;



@SpringBootTest
class ProductServiceTest{

    @Autowired
    ProductService productService;

    //传统方式
    @Test
    public void insert() {
        CurrentUserHolder.set("tom");
        productService.insert(new Product());
    }

    //切面方式
    @Test
    public void delete() {
        CurrentUserHolder.set("admin");
        productService.delete("1");
    }
}

运行:
运行传统方法insert,出现错误,如果想要正确把tom 改为 admin 测试即可
AOP详解与实例第一章_第3张图片
运行AOP注解方式如下,如果想要错误把admin改为tom即可
AOP详解与实例第一章_第4张图片
是不是初步了解了呢,下面我讲下语法使用等介绍,请看 “AOP详解与实例第二章” 。

你可能感兴趣的:(AOP详解与实例第一章)