1 编程范式

  1.1 面向过程

  1.2 面向对象

  1.3 面向切面编程

  1.4 函数式编程

  1.5 事件驱动编程

2 什么是面向切面编程

  2.1 是一种编程范式,而不是一种编程语言

  2.2 解决一些特定的问题

  2.3 作为面向对象编程的一种补充

3  AOP产生的初衷

  3.1 解决代码重复性问题 Don't Repeat Yourself

  3.2 解决关注点分离问题 Separation of Concerns

    3.2.1 水平分离(技术上划分)

      控制层 -> 服务层 -> 持久层

    3.2.2 垂直分离(模块上划分)

      模块划分

    3.2.3 切面分离(功能上划分)

      分离功能性需求和非功能性需求

4 使用AOP的好处

  4.1 集中处理某一个关注点、横切逻辑

  4.2 可以很方便地添加、删除关注点

  4.3 侵入性减少,增强代码可读性和可维护性

  

5 AOP的使用场景

  5.1 权限控制

  5.2 缓存控制

  5.3 事物控制

  5.4 审计日志

  5.5 性能监控

  5.6 分布式追踪

  5.7 异常处理

  

6 利用传统方法实现权限验证

  6.1 创建一个springBoot项目

    下载地址:点击前往

  6.2 新建一个Product实体类

package cn.test.demo.base_demo.entity;

/**
* @author 王杨帅
* @create 2018-04-29 17:11
* @desc 商品实体类
**/
public class Product {
private Integer id;
private String name; public Product() {
} public Product(Integer id, String name) {
this.id = id;
this.name = name;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

Product.java

  6.3 新建一个权限模拟类

    该类主要用来设定用户和获取用户

package cn.test.demo.base_demo.security;

/**
* @author 王杨帅
* @create 2018-04-29 17:15
* @desc 模拟用户登录,该类可以设定用户和获取用户
**/
public class CurrentSetHolder {
private final static ThreadLocal<String> holder = new ThreadLocal<>(); /**
* 获取用户
* @return
*/
public static String get() {
return holder.get() == null ? "unknown" : holder.get();
} /**
* 设定用户
* @param user
*/
public static void set(String user) {
holder.set(user);
}
}

CurrentSetHolder.java

  6.4 新建一个权限校验类

    该类主要用于判断当前用户是否是“admin”用户

package cn.test.demo.base_demo.service;

import cn.test.demo.base_demo.security.CurrentSetHolder;
import org.springframework.stereotype.Component; /**
* @author 王杨帅
* @create 2018-04-29 17:19
* @desc 权限校验服务类
**/
@Component
public class AuthService { /**
* 权限检查,如果用户不是 “admin" 就会报错
*/
public void checkAccess() {
String user = CurrentSetHolder.get();
if (!"admin".equals(user)) {
throw new RuntimeException("operation not allow.");
}
}
}

AuthService.java

  6.5 新建ProductService类

    该类主要实现对Product的一些操作

package cn.test.demo.base_demo.service;

import cn.test.demo.base_demo.entity.Product;
import cn.test.demo.base_demo.security.AdminOnly;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; /**
* @author 王杨帅
* @create 2018-04-29 17:14
* @desc 商品服务层
**/
@Service
@Slf4j
public class ProductService { private final String className = getClass().getName(); /**
* 依赖注入权限校验服务
*/
@Autowired
private AuthService authService; public void insert(Product product) {
authService.checkAccess(); // 利用权限校验对象进行权限校验,不是 ”admin" 就会报错
log.info("===/" + className + "/insert===新增数据");
} @AdminOnly
public void delete(Integer id) {
// authService.checkAccess(); // 利用权限校验对象进行权限校验
log.info("===/" + className + "/delete===删除数据");
}
}

ProductService.java

  6.6 创建一个服务层测试类

    在调用ProductService的insert方法前对用户进行设定

package cn.test.demo.base_demo.service;

import cn.test.demo.base_demo.entity.Product;
import cn.test.demo.base_demo.security.CurrentSetHolder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.omg.CORBA.Current;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
public class ProductServiceTest { /**
* 依赖注入权限
*/
@Autowired
private ProductService productService; /**
* productService.insert(product) 方法中有权限验证,如果不是“admin"用户就会报错
*/
@Test
public void annonInsert() {
CurrentSetHolder.set("bob"); // 设置用户
Product product = new Product();
productService.insert(product);
} /**
* productService.insert(product) 方法中有权限验证,如果不是“admin"用户就会报错
*/
@Test
public void adminInsert() {
CurrentSetHolder.set("admin"); // 设置用户
Product product = new Product();
productService.insert(product);
} @Test
public void delete() throws Exception {
} }

ProductServiceTest.java

7 利用AOP实现权限验证

  7.1 新建一个springBoot项目

    下载地址:点击前往

  7.2 创建一个Product实体类

package cn.test.demo.base_demo.entity;

/**
* @author 王杨帅
* @create 2018-04-29 17:11
* @desc 商品实体类
**/
public class Product {
private Integer id;
private String name; public Product() {
} public Product(Integer id, String name) {
this.id = id;
this.name = name;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

Product.java

  7.3 创建一个AdminOnly注解

package cn.test.demo.base_demo.security;

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 AdminOnly {
}

AdminOnly.java

  7.4 新建一个权限模拟类

    该类主要用来设置用户和获取用户

package cn.test.demo.base_demo.security;

/**
* @author 王杨帅
* @create 2018-04-29 17:15
* @desc 模拟用户登录,该类可以设定用户和获取用户
**/
public class CurrentSetHolder {
private final static ThreadLocal<String> holder = new ThreadLocal<>(); /**
* 获取用户
* @return
*/
public static String get() {
return holder.get() == null ? "unknown" : holder.get();
} /**
* 设定用户
* @param user
*/
public static void set(String user) {
holder.set(user);
}
}

CurrentSetHolder.java

  7.5 创建一个切面类

    该类主要对所有使用了@AdminOnly注解的方法进行权限校验

package cn.test.demo.base_demo.security;

import cn.test.demo.base_demo.service.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; /**
* @author 王杨帅
* @create 2018-04-29 17:37
* @desc 权限检查的AOP类
**/
@Aspect
@Component
public class SecurityAspect {
@Autowired
AuthService authService; @Pointcut("@annotation(AdminOnly)")
public void adminOnly(){ } @Before("adminOnly()")
public void check(){
authService.checkAccess();
}
}

SecurityAspect.java

  7.6 新建一个ProductService服务类

    该类的delete方法用了@AdminOnly注解,所以delete方法会进行权限校验

package cn.test.demo.base_demo.service;

import cn.test.demo.base_demo.entity.Product;
import cn.test.demo.base_demo.security.AdminOnly;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; /**
* @author 王杨帅
* @create 2018-04-29 17:14
* @desc 商品服务层
**/
@Service
@Slf4j
public class ProductService { private final String className = getClass().getName(); /**
* 依赖注入权限校验服务
*/
@Autowired
private AuthService authService; public void insert(Product product) {
authService.checkAccess(); // 利用权限校验对象进行权限校验,不是 ”admin" 就会报错
log.info("===/" + className + "/insert===新增数据");
} @AdminOnly
public void delete(Integer id) {
// authService.checkAccess(); // 利用权限校验对象进行权限校验
log.info("===/" + className + "/delete===删除数据");
}
}

ProductService.java

  7.7 创建一个测试类

    productService.delete(id) 方法中有权限验证,如果不是“admin"用户就会报错【利用AOP实现的】

package cn.test.demo.base_demo.service;

import cn.test.demo.base_demo.entity.Product;
import cn.test.demo.base_demo.security.CurrentSetHolder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.omg.CORBA.Current;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
public class ProductServiceTest { /**
* 依赖注入权限
*/
@Autowired
private ProductService productService; /**
* productService.insert(product) 方法中有权限验证,如果不是“admin"用户就会报错【利用传统方法实现的】
*/
@Test
public void annonInsert() {
CurrentSetHolder.set("bob"); // 设置用户
Product product = new Product();
productService.insert(product);
} /**
* productService.insert(product) 方法中有权限验证,如果不是“admin"用户就会报错【利用传统方法实现的】
*/
@Test
public void adminInsert() {
CurrentSetHolder.set("admin"); // 设置用户
Product product = new Product();
productService.insert(product);
} /**
* productService.delete(id) 方法中有权限验证,如果不是“admin"用户就会报错【利用AOP实现的】
*/
@Test
public void annoDelete() throws Exception {
CurrentSetHolder.set("peter");
productService.delete(3);
} /**
* productService.delete(id) 方法中有权限验证,如果不是“admin"用户就会报错【利用AOP实现的】
*/
@Test
public void adminDelete() {
CurrentSetHolder.set("admin");
productService.delete(4);
} }

ProductServiceTest.java

  7.8 源代码

    点击前往

SpringAOP01 利用AOP实现权限验证、利用权限验证服务实现权限验证的更多相关文章

  1. nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证

    http模块内部封装了http服务器和客户端,因此Node.js不需要借助Apache.IIS.Nginx.Tomcat等传统HTTP服务器,就可以构建http服务器,亦可以用来做一些爬虫.下面简单介 ...

  2. 利用AOP与ToStringBuilder简化日志记录

    刚学spring的时候书上就强调spring的核心就是ioc和aop blablabla...... IOC到处都能看到...AOP么刚开始接触的时候使用在声明式事务上面..当时书上还提到一个用到ao ...

  3. SpringBoot31 整合SpringJDBC、整合MyBatis、利用AOP实现多数据源

    一.整合SpringJDBC 1  JDBC JDBC(Java Data Base Connectivity,Java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系数 ...

  4. JavaEE权限管理系统的搭建(六)--------使用拦截器实现菜单URL的跳转权限验证和页面的三级菜单权限按钮显示

    本小结讲解,点击菜单进行页面跳转,看下图,点击管理员列表后会被认证拦截器首先拦截,验证用户是否登录,如果登录就放行,紧接着会被权限验证拦截器再次拦截,拦截的时候,会根据URL地址上找到对应的方法,然后 ...

  5. 如何利用aop的环绕消息处理log, 以及各种坑的记录

    如何利用aop的环绕消息处理log, 以及各种坑的记录 本文链接: https://www.cnblogs.com/zizaiwuyou/p/11667423.html 因为项目里有很多地方要打log ...

  6. 验证销售部门的数据查看权限-脚本demo

    1 # coding:utf-8 2 ''' 3 @file: run_old.py 4 @author: jingsheng hong 5 @ide: PyCharm 6 @createTime: ...

  7. SpringBoot2.x整合Email并利用AOP做一个项目异常通知功能

    因为不知aop能干嘛,因此用aop做个小功能,再结合最近学的springboot-Email做了个系统异常自动邮件通知的功能, 感觉满满的成就感. AOP不懂的可以看上一篇:https://www.c ...

  8. 利用AOP切面打印项目中每个接口的运行情况

    1.前言 AOP切面技术,大家应该都听知道,Spring框架的主要功能之一. AOP切面的用途很广,其中一个常见的用途就是打印接口方法的运行日志和运行时间. 日志对于一个项目很是重要,不仅有助于调错, ...

  9. geoserver控制服务访问权限-类似百度地图的key

    目录 缘起 可行性分析 如何实现key验证访问 如何控制key能访问哪些地图服务? 如何实现服务器ip白名单 流程梳理 申请key 访问地图 实施步骤 拦截器设置 配置key验证规则 配置服务拦截规则 ...

随机推荐

  1. [QT]问题记录-控件初始化导致程序异常关闭

    qt新手,在设置 pushButton 的字体颜色时,出现软件异常闭,代码如下: 按钮的初始化在  ui->setupUi(this); 前边,会出现一下问题. 解决办法:将按钮的初始化在  u ...

  2. SSH框架(1)

    一. SSH框架相关的面试题:   1.  BeanFactory的作用是什么?   [中] BeanFactory是配置.创建.管理bean的容器,有时候也称为bean上下文.Bean与bean的依 ...

  3. [Luogu3769][CH弱省胡策R2]TATT

    luogu 题意 其实就是四维偏序. sol 第一维排序,然后就只需要写个\(3D-tree\)了. 据说\(kD-tree\)的单次查询复杂度是\(O(n^{1-\frac{1}{k}})\).所以 ...

  4. checkStype和findBugs校验

    IDEA可以直接在setting中下载checkStyle和findBugs <plugin> <groupId>org.codehaus.mojo</groupId&g ...

  5. MDK中STM32使用Printf函数详细解析【转载】

    在用MDK调试STM32板子串口时,为了方便串口调试,调用了printf()函数,用Keil仿真是,串口不能正确的输出,软件仿真时,总是卡在那 里.有点纳闷,然后调用USART_SendData()函 ...

  6. Linux:远程连接 SSH

    一.认识 SSH 定义 SSH(Secure shell):安全外壳协议:是建立在应用层基础上的安全协议: 通过 SSH 进行服务端连接,不容易被窃取信息: 连接服务器 ssh 服务器名 + @ + ...

  7. Annotation之三:自定义注解示例,利用反射进行解析

    @Retention定义了该Annotation被保留的时间长短有3中RetentionPolicy.SOURCE源文件有效,RetentionPolicy.CLASS:在class文件中有效,Ret ...

  8. kali 软件源 包含virtualbox所需头文件

    # deb cdrom:[Debian GNU/Linux 7.0 _Kali_ - Official Snapshot i386 LIVE/INSTALL Binary 20130905-08:50 ...

  9. Java中的阻塞和非阻塞IO包各自的优劣思考(经典)

    Java中的阻塞和非阻塞IO包各自的优劣思考 NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式. 反应器(Reactor):用于事件多路分离和分派的体系结构模式 通常的,对一个 ...

  10. python开发面向对象基础:组合&继承

    一,组合 组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合      人类装备了武器类就是组合 1.圆环,将圆类实例后传给圆环类 #!/usr/bin/env python #_*_ ...