Spring中整合了AOP的功能,虽然有不足,没有专门做AOP框架的那么完美,但是用一用感觉还是不错的

一些概念:

AOP 面向切面编程

aspect 切面/切面类(我个人认为一个真正被解耦的程序,切面类中的功能可以切入到 任何一个目标类中 无所谓是service层或者说是dao层中的类)

joinPoint 连接点

在spring的aop中只有 类中的方法 可以做连接点,每一个方法都可以是一个连接点.

pointCut 切入点

一组连接点的集合

advice 通知/拦截器

用来控制切面类将来到底是织入到切入点的前面、后面或者是抛异常的时候。

adivsor 增强器
用来筛选类中的哪些方法是我们的连接点(哪些方法需要被拦截).

target 目标对象

proxy 代理对象

wave 织入

-----------------------

advice(通知)的类型:

前置通知(Before advice):
在某些连接点(join point)之前执行的通知

返回后通知(After returning advice):
在某些连接点(join point)正常完成后执行的通知(方法正常结束,没有异常)

抛出异常后通知(After throwing advice):
在某些连接点(join point)抛出异常退出时执行的通知

后通知(After (finally) advice):
当某些连接点(join point)退出的时候执行的通知

环绕通知(Around Advice):
包围一个连接点(join point)的通知,例如事务的处理,就需要这样的通知,因为事务需要在方法前开启,在方法后提交,以及方法抛出异常时候回滚

注:在spring中,连接点(join point)指的就是方法

Spring中提供了AOP的实现方式 在XMl中配置只需要三步就可以实现

1.配置目标类
2.配置拦截器(配置切面类【可选】)
3.配置代理对象

配置xml文件:

1.首先是配置目标类

<!-- 配置dao层对象 -->
<bean id="dao" class="com.briup.aop.dao.AccountDaoImpl"/> <!-- 配置一个测试账户 -->
<bean name="account" class="com.briup.aop.pojo.Account">
<property name="id" value="1"></property>
<property name="name" value="tom"></property>
<property name="balance" value="1000"></property>
</bean> <!-- 配置目标对象 -->
<bean name="target"
class="com.briup.aop.service.AccountServiceImpl">
<property name="accountDao" ref="dao"></property>
<property name="account" ref="account"></property>
</bean>

2.配置拦截器

<!-- 配置切面类 -->
<bean name="logger" class="com.briup.aop.aspect.MyLogger"></bean> <!-- 配置advice -->
<bean name="beforeAdvice" class="com.briup.aop.before.BeforeAdvice">
<!-- 注入切面类对象 -->
<property name="logger" ref="logger"></property>
</bean>

3.配置代理对象

<!-- 这里使用的是spring的一个代理对象工厂类产生的 -->
<bean name="proxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 注入目标对象 -->
<property name="target" ref="target"></property> <!-- 注入目标对象所实现的接口 可以有多个接口 -->
<!-- 注入代理类需要实现的接口 代理类实现接口与目标类实现接口相同 -->
<property name="proxyInterfaces">
<list>
<value>com.briup.aop.service.IAccountService</value>
</list>
</property> <!-- 注入advice 可以有多个 -->
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
</list>
</property> </bean>

这样配置有三个问题:
1.这个目标类对应接口下的方法都被加入了功能
2.需要为每一个目标类进行配置
3.目标类必须实现接口

首先我们解决第一个问题
我们的Spring中提供了advisor(增强器),增强器包装了一下advice(拦截器),可以筛选向接口中的那个方法添加功能

1.首先是配置目标类

<!-- 配置dao层对象 -->
<bean id="dao" class="com.briup.aop.dao.AccountDaoImpl"/> <!-- 配置一个测试账户 -->
<bean name="account" class="com.briup.aop.pojo.Account">
<property name="id" value="1"></property>
<property name="name" value="tom"></property>
<property name="balance" value="1000"></property>
</bean>
<!-- 配置目标对象 -->
<bean name="target"
class="com.briup.aop.service.AccountServiceImpl">
<property name="accountDao" ref="dao"></property>
<property name="account" ref="account"></property>
</bean>

2.配置拦截器

<!-- 配置切面类 -->
<bean name="logger" class="com.briup.aop.aspect.MyLogger"></bean> <!-- 配置advice -->
<bean name="beforeAdvice" class="com.briup.aop.before.BeforeAdvice">
<!-- 注入切面类对象 -->
<property name="logger" ref="logger"></property>
</bean>

3.添加增强器

<!-- 配置advisor 增强器-->
<!-- 作用:筛选要拦截(要代理)的方法 -->
<bean name="advisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 注入advice-->
<property name="advice" ref="beforeAdvice"></property>
<!-- 注入需要被拦截的目标对象中的方法(连接点) -->
<property name="patterns">
<list>
<value>.*bankAction</value> <!--单个字符出现0到多次-->
</list>
</property>
</bean>
<!--RegexpMethodPointcutAdvisor默认的正则表达式选择方法-->
<!--NameMatchMethodPointcutAdvisor按照方法名匹配-->

4.配置代理对象

<!-- 这里使用的是spring的一个代理对象工厂类产生的 -->
<bean name="proxy"
class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 注入目标对象 -->
<property name="target" ref="target"></property> <!-- 注入目标对象所实现的接口 可以有多个接口 -->
<!-- 注入代理类需要实现的接口 代理类实现接口与目标类实现接口相同 -->
<property name="proxyInterfaces">
<list>
<value>com.briup.aop.service.IAccountService</value>
</list>
</property> <!-- 注入advice/advisor 可以有多个 -->
<property name="interceptorNames">
<list>
<value>advisor</value>
</list>
</property>
</bean>

我们处理了第一个问题,被处理的方法可以指定了

我们开始解决第二个问题
自动的进行配置:自动代理:DefaultAdvisorAutoProxyCreator类的使用

xml配置文件:

1.配置拦截器

<!-- 配置切面类 -->
<bean name="logger" class="com.briup.aop.aspect.MyLogger"></bean> <!-- 配置advice -->
<bean name="beforeAdvice"
class="com.briup.aop.before.BeforeAdvice">
<!-- 注入切面类对象 -->
<property name="logger" ref="logger"></property>
</bean>

2.添加增强器

<!-- 配置advisor -->
<!-- 作用:筛选要拦截的方法 -->
<bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 注入advice -->
<property name="advice" ref="beforeAdvice"></property>
<!-- 注入需要被拦截的目标对象中的方法 -->
<property name="patterns">
<list>
<value>.*bankAction</value>
</list>
</property>
</bean>

配置目标对象,这里的对象中只要有增强器中的方法,就可以当作代理对象,Cgilb代理默认的将含有增强器中的方法的
所有对象都进行了处理,比如以下这个target对象,从容器中拿出后就是加入了功能的了,但是这些对象得要放在一个容器下面

在Spring中最需要注意的就是对象在不在容器中,对象不在容器中就没办法受到Spring框架的控制了

<bean name="target"
class="com.briup.aop.service.AccountServiceImpl">
</bean>

3.实现自动代理

<!-- 配置代理对象 -->
<!-- 这里使用自动代理的方式 autoproxy -->
<!-- 注意:这不是一个工厂类,所以不能用过proxy来拿代理对象 -->
<bean name="proxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
</bean>

这样做就可以自动的对需要功能的方法进行代理处理了,也不用实现接口了

使用自动代理的时候需要注意的方面:
1.当前的配置里面"一定要有"一个advisor的配置
2.不需要向自动代理类中注入任何信息
3.不管目标对象是否实现了一个或多接口,自动代理的方式都能够为它产生代理对象(CGLib的方式).
4.从spring容器中拿代理对象的时候,需要通过目标对象的名字来拿。
5.spring如何确定配置文件中哪个bean是作为目标对象:
通过advisor中筛选的方法,如果这个bean中含有advisor中所配置的方法,则这个bean将来称为我们的目标对象进行代理

但是又有问题来了:
我们对所有含有同名方法的类对象进行了处理,如果想为指定类对象中的方法进行处理呢?

Spring同样进行了处理:

通过名字进行自动代理:BeanNameAutoProxyCreator类的使用

xml配置文件:

1.配置拦截器

<!-- 配置切面类 -->
<bean name="logger" class="com.briup.aop.aspect.MyLogger"></bean>
<!-- 配置advice -->
<bean name="beforeAdvice"
class="com.briup.aop.before.BeforeAdvice">
<!-- 注入切面类对象 -->
<property name="logger" ref="logger"></property>
</bean>

2.添加增强器

<!-- 配置advisor -->
<!-- 作用:筛选要拦截的方法 -->
<bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 注入advice -->
<property name="advice" ref="beforeAdvice"></property>
<!-- 注入需要被拦截的目标对象中的方法 -->
<property name="patterns">
<list>
<value>.*bankAction</value>
</list>
</property>
</bean>

<!-- 配置目标对象 -->

<bean name="target" class="com.briup.aop.service.AccountServiceImpl"> </bean>

<bean name="target2" class="com.briup.aop.service.AccountServiceImpl"> </bean>

<bean name="target3" class="com.briup.aop.service.AccountServiceImpl"></bean>

3.实现自动代理

<!-- 配置代理对象 -->
<!-- 这里使用自动代理的方式 autoproxybyname -->
<bean name="proxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 注入需要被代理的对象名字 -->
<property name="beanNames">
<list>
<value>target</value>
<value>target2</value>
<value>dao</value>
<value>service*</value>
</list>
</property> <!-- 注入advice或者advisor -->
<property name="interceptorNames">
<list>
<value>advisor</value>
</list>
</property>
</bean>

使用byName自动代理的时候需要注意的方面:
1.当前的配置里面"有没有"advisor的配置"都没关系"
有advisor可以精确选择加强功能的方法,没有就是类中的所有方法了

2.需要向自动代理类中注入被代理目标对象的名字已经advice或者advisor
就是说advisor中指定的方法在 被代理目标对象 中存在

3.不管目标对象是否实现了一个或多接口,自动代理的方式都能够为它产生代理对象.

4.从spring容器中拿代理对象的时候,需要通过目标对象的名字来拿。
这一点在DefaultAdvisorAutoProxyCreator的使用中就说过了
可以说 目标对象加入了功能,变成了代理对象

Spring中封装了AspectJ
所以我们也可以使用到这种框架的功能了,Spring中提供了aop:config标签,使用aop的专用标签来完成相关的配置.这个标签我也是正在研究,据说挺好用的☺。

Spring中AOP的实现的更多相关文章

  1. Spring中AOP原理,源码学习笔记

    一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...

  2. Spring中AOP简介与切面编程的使用

    Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...

  3. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

  4. Spring 中aop切面注解实现

    spring中aop的注解实现方式简单实例   上篇中我们讲到spring的xml实现,这里我们讲讲使用注解如何实现aop呢.前面已经讲过aop的简单理解了,这里就不在赘述了. 注解方式实现aop我们 ...

  5. Spring中AOP相关源码解析

    前言 在Spring中AOP是我们使用的非常频繁的一个特性.通过AOP我们可以补足一些面向对象编程中不足或难以实现的部分. AOP 前置理论 首先在学习源码之前我们需要了解关于AOP的相关概念如切点切 ...

  6. AOP 与 Spring中AOP使用(上)

    AOP简介 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程, 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP是OOP的延续 ...

  7. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  8. 浅析Spring中AOP的实现原理——动态代理

    一.前言   最近在复习Spring的相关内容,刚刚大致研究了一下Spring中,AOP的实现原理.这篇博客就来简单地聊一聊Spring的AOP是如何实现的,并通过一个简单的测试用例来验证一下.废话不 ...

  9. Spring中AOP相关的API及源码解析

    Spring中AOP相关的API及源码解析 本系列文章: 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configuration注解? 谈谈Spring ...

  10. Spring中AOP的模拟实现

    什么是AOP? 面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面 1.面向切面编程提供声明式事务管理 2.spring支持用户自定义的切面 面向 ...

随机推荐

  1. 23.包、修饰符、jar

    下面都是在记事本里面写代码 1. 包的定义格式: package 包名(全小写)  例如: package a; 注意: 1)package语句必须位于java文件的第一个语句 2.编译运行 注意: ...

  2. thinkphp 查询缓存

    对于及时性要求不高的数据查询,我们可以使用查询缓存功能来提高性能,而且无需自己使用缓存方法进行缓存和获取. 大理石平台价格 查询缓存功能支持所有的数据库,并且支持所有的缓存方式和有效期. 在使用查询缓 ...

  3. 后缀自动机求多串LCS——spojlcs2

    /* 每个状态存最长匹配长度,然后多个串匹配过程中取最小的最长匹配长度 和LCS1不同的地方:LCS只要维护住当前匹配长度和最长匹配长度即可,但是多串匹配需要维护的是每个状态结点(即后缀树上)的信息 ...

  4. DELPHI中如何闪烁应用程序窗口或任务栏按钮

    使用FlashWindowEx函数: 一.设置FlashWInfoDelphi中TFlashWInfo申明如下:TypeTFlashWInfo = record cbSize : LongInt; h ...

  5. APIO 2007 风铃

    题目描述 你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西. 你准备给 Ike 买一个风铃.风铃是一种多层的装饰品,一般挂在天花板上. 每个风 ...

  6. NX二次开发-UFUN打开选择文件夹对话框UF_UI_create_filebox

    #include <uf.h> #include <uf_ui.h> #include <string> using namespace std; string O ...

  7. 随意从Android端抓取一些数据包看到的协议

    如题,就打开了某银行客户端,登录,查询余额,退出 打开支付宝钱包,登录,来回转账到余额宝 中间收到微信的消息 看到了以下协议: 银行客户端的:DNS (连接银行网站时使用,网站server返回也是用的 ...

  8. kma 2019CSP前刷题记录

    2019/10/25 \([LNOI2014]\ LCA\) \([Luogu\ P2774]\) 方格取数问题 \(Gauss\)消元板 \([JSOI2008]\)球形空间产生器 2019/10/ ...

  9. java-day12

    数据结构 常用的数据存储结构:栈,队列,数组,列表,红黑树. 栈:先进后出(入口和出口在用一侧) 队列:先进先出 数组: 查询快:因为数组的地址是连续的,通过数组的首地址找到数组中的元素. 增/删慢: ...

  10. 002-Java数据类型

    Java数据类型 基本数据类型 和 引用数据类型 基本数据类型 整型:byte - 8bit / short - 2字节 / int - 4字节 / long - 8字节 浮点型:float doub ...