需求:
1、拦截所有业务方法
2、判断用户是否有权限,有权限就让他执行业务方法,没有权限就不允许执行。(是否有权限是根据user是否为null作为判断依据)

思考:

我们该如何实现?

思路1:

  我们在每个业务方法上面加上判断语句。

否决掉了。代码过多,不灵活如果我需要更改需求就要挂掉。

解决方式:

使用动态代理实现。

Proxy动态代理。要求:被代理的对象需要有父接口。

准备代码:

package cn.itcast.service;

public interface PersonService {
public abstract String getPersonName(Integer personId);
public abstract void save(String name);
public abstract void update(String name,Integer personId);
} package cn.itcast.service.impl; import cn.itcast.service.PersonService; public class PersonServiceBean implements PersonService{
private String user=null; public PersonServiceBean(){} public String getUser() {
return user;
} public PersonServiceBean(String user){
this.user=user;
} public String getPersonName(Integer personId) {
System.out.println("我是getPersonName()方法");
return "xxx";
} public void save(String name) {
System.out.println("我是save()方法");
} public void update(String name, Integer personId) {
System.out.println("我是update()方法");
} }

Proxy代理:

package cn.itcast.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import cn.itcast.service.impl.PersonServiceBean; public class JDKProxyFactory implements InvocationHandler{
private Object targetObject; public Object createProxyInstance(Object targetObject){
this.targetObject=targetObject;
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {//环绕通知
PersonServiceBean bean=(PersonServiceBean) targetObject;
Object result=null;
if(bean!=null && bean.getUser()!=null){
try{
//...advice()-->前置通知
result=method.invoke(targetObject, args);
//...afteradvice()-->后置通知
}catch(RuntimeException e){
//exceptionadvice()-->例外通知
}finally{
//finallyadvice()-->最终通知
} }
return result;
}
}

如果操作的目标对象没有父接口,应该怎么做呢?

使用cglib.jar生成代理对象

原理:

生成的代理对象继承自原对象,重写了原对象的除了final外方法

导入jar:

cglib-nodep-2.1_3.jar

主要代码:

package cn.itcast.aop;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import cn.itcast.service.impl.PersonServiceBean; public class CGlibProxyFactory implements MethodInterceptor{
private Object targetObject; public Object createProxyInstance(Object targetObject){
this.targetObject=targetObject;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());//继承了目标类,对目标类里面所有非final方法进行和覆盖,在覆盖的方法内添加自身代码
enhancer.setCallback(this);
return enhancer.create();
} @Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
PersonServiceBean bean=(PersonServiceBean) targetObject;
Object result=null;
if(bean!=null && bean.getUser()!=null){
result=method.invoke(targetObject, args);
}
return result;
}
}

spring的AOP操作的内部原理就是使用的上面两种动态代理方式。

现在讲讲AOP的一些概念:

横切性关注点

前面我们思考的拦截对象拦截方式等叫做横切性关注点。
对什么进行拦截,拦截后应该做什么,这些思考的步骤,我们可以定义为横切性关注点。

aspect(切面):
指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类时对物体特征的抽象,而切面是横切性关注点的抽象。

joinpoint(连接点)
所谓连接点,就是指那些被拦截到的方法。在上面的例子中,练接点是绝大部分方法(非native),在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或者类构造器

pointcut(切入点):
所谓切入点,就是指的我们需要拦截的连接点的定义,在上面的例子中指的是业务方法

advice(通知):拦截到连接点之后需要做的事

 

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {//环绕通知
PersonServiceBean bean=(PersonServiceBean) targetObject;
Object result=null;
if(bean!=null && bean.getUser()!=null){
try{
//...advice()-->前置通知
result=method.invoke(targetObject, args);
//...afteradvice()-->后置通知
}catch(RuntimeException e){
//exceptionadvice()-->例外通知
}finally{
//finallyadvice()-->最终通知
} }
return result;
}

target(目标对象):

代理的目标对象

weave(织入):
将aspects应用到target对象并导致proxy对象创建的过程称为织入

introduction(引入):
在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或者Field

springAOP原理以及概念的更多相关文章

  1. Atitit WebDriver技术规范原理与概念

    Atitit WebDriver技术规范原理与概念 1. Book haosyo ma1 2. WebDriver是W3C的一个标准,由Selenium主持.1 3. WebDriver如何工作 (z ...

  2. SpringAOP原理分析

    目录 Spring核心知识 SpringAOP原理 AOP编程技术 什么是AOP编程 AOP底层实现原理 AOP编程使用 Spring核心知识 Spring是一个开源框架,Spring是于2003年兴 ...

  3. SpringAOP原理

    原理 AOP(Aspect Oriented Programming),也就是面向方面编程的技术.AOP基于IoC基础,是对OOP的有益补充.AOP将应用系统分为两部分,核心业务逻辑(Core bus ...

  4. SpringAOP 原理解析

    什么是AOP? 1: 传统的OOP编程他的代码逻辑是一种自上向下, 而在这些自上而下的过程中会产生一些横切性的问题,比如说:日志信息,权限校验认证,事务等, 2: 这些横切性问题,往往与我们的主业务逻 ...

  5. Spring框架IOC和AOP的实现原理(概念)

    IoC(Inversion of Control) (1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控.控制权由应用代码中 ...

  6. Lucene原理之概念

    概念: 数据分两种: 1.结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等. 2.非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等.(半结构化数据:如XML,HTML等, ...

  7. IO流的原理和概念

    在程序中如何读写文件?不同的编程语言有不同的方式,而 JAVA 则提出了“流”的概念,通过“流”来读写文件 什么是流: 流(Stream)是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通 ...

  8. HashMap原理(一) 概念和底层架构

    HashMap在Java开发中使用的非常频繁,可以说仅次于String,可以和ArrayList并驾齐驱,准备用几个章节来梳理一下HashMap.我们还是从定义一个HashMap开始. HashMap ...

  9. webpack-dev-server 小记 原理介绍 概念解读

    使用 DevServer 提供 HTTP 服务而不是使用本地文件预览 监听文件的变化并自动刷新网页,做到实时预览 支持 Source Map,以方便调试 对于这些,Webpack 都为我们考虑好了.W ...

随机推荐

  1. UNP学习笔记(第二章:传输层)

    本章的焦点是传输层,包括TCP.UDP和SCTP. 绝大多数客户/服务器网络应用使用TCP或UDP.SCTP是一个较新的协议. UDP是一个简单的.不可靠的数据报协议.而TCP是一个复杂.可靠的字节流 ...

  2. JSON 值转换

    var Txt = '{"a":"1","b":"5","c":"5",&quo ...

  3. bigAutocomplete实现联想

    直接举例说明: //xx联想 var list = $(".js-xxxx").text();//需要联想出的内容的list,该list由后台传入,保存在jsp页面,js取隐藏域值 ...

  4. D类功放基础简介

    DAC和D类PA的开关时序是先开dac再开D类pa,先关D类pa再关dac

  5. springboot+async异步接口实现和调用

    什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行. 如何实现异步调用? 多线程, ...

  6. struct timeval 和 struct timespec

    struct timeval { time_t tv_sec; suseconds_t tv_usec; }; 測试代码例如以下: #include <stdio.h> #include ...

  7. Android setTag()与getTag(),与set多个setTag()

    首先我们要知道setTag方法是干什么的,SDK解释为 Tags Unlike IDs, tags are not used to identify views. Tags are essential ...

  8. 转载 ----Android学习笔记 - 蓝牙篇 (Bluetooth)

      1.什么是蓝牙  Bluetooth是目前使用的最广泛的无线通讯协议之一  主要针对短距离设备通讯(10米)  常用于连接耳机.鼠标和移动通讯设备等 2.发现周围蓝牙设备  BluetoothAd ...

  9. centOS7 安装nginx+php+mysql

    nginx安装 本文是介绍使用源码编译安装,包括具体的编译参数信息. 正式开始前,编译环境gcc g++ 开发库之类的需要提前装好. 安装make: yum -y install gcc automa ...

  10. Android API Guides---Storage Access Framework

    存储訪问架构 Android 4.4系统(API级别19)推出存储訪问框架(SAF).新加坡武装部队变得很easy,为用户在其全部自己喜欢的文件存储提供商的浏览和打开文档,图像和其它文件.一个标准的, ...