需求:
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. MySQL -进阶

    一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用 SELECT * FROM(SELE ...

  2. PHP正则匹配6到16位字符组合(且只能为数字、字母、下划线)

    php正则匹配6到16位的字符串. 只允许包含数字.字母.下划线组成的6到16位字符,符合返回ture,否则返回false. 解答: 6到16位,正则可以这样写:{6,16}. 任意的字符6到16位的 ...

  3. 【demo练习三】:图片水平滚动、点击按钮变更图片动画

    要求:四张图片水平滚动,每隔5秒进行一次循环,点击按钮随机变更图片. XAML前台代码: <Window x:Class="图片滚动.MainWindow" xmlns=&q ...

  4. Git --更改远程分支名

    git更新远程分支名字 git checkout old_branch git branch -m old_branch new_branch git push --delete origin old ...

  5. struts2 jsp提交日期类型转换及国际化实现

    概述:下面通过jsp提交输入注册信息信息,同时完成过程文件国家化问题演示说明.[注册日期转换用注解方式实现] 工程截图: 注册页面jsp文件: <%@ page language="j ...

  6. Linux 开启端口,操作防火墙

    命令行方式:    添加10002端口方法 1.vi etc/sysconfig/iptables 2. 开放端口命令:-A INPUT -p tcp -m state --state NEW -m ...

  7. GS给客户单发包以及m_queGcWait(所有GC共享)

    GS给客户单发包以及m_queGcWait(所有GC共享) send_stat BaseChannel::SendCmd(int nCmd, void* pData, int nLen) { Prot ...

  8. EasyNVR H5无插件摄像机直播解决方案前端解析之:videojs的使用

    video.js的基本使用方法 一.videojs的初始化加载 videojs初始化加载分为两中 1.标签式加载 在引入videojs加载文件的前提下,可以在video标签中添加属性值"da ...

  9. jQuery学习笔记(9)--jquery中的事件--$(document).ready()

    1.$(document).ready()方法是事件模块中最重要的一个函数,可以极大地提高web应用程序的相应速度. 2.执行时机:DOM就绪后就会执行,而javascript中window.onlo ...

  10. Notepad++ QuickText 插件的 HTML 配置: \Notepad++\plugins\Config\QuickText.ini

    # 缩写的注解 abbr=<abbr title=''>$</abbr> # 覆盖默认的文本方向 bdo=<bdo dir='rtl'>$</bdo> ...