Spring的传统AOP

AOP:不是由Spring定义.AOP联盟的组织定义.
Spring中的通知:(增强代码)

  • 前置通知 org.springframework.aop.MethodBeforeAdvice
    * 在目标方法执行前实施增强

  • 后置通知 org.springframework.aop.AfterReturningAdvice
    * 在目标方法执行后实施增强
  • 环绕通知 org.aopalliance.intercept.MethodInterceptor
    * 在目标方法执行前后实施增强
  • 异常抛出通知 org.springframework.aop.ThrowsAdvice
    * 在方法抛出异常后实施增强
  • 引介通知 org.springframework.aop.IntroductionInterceptor(课程不讲.)
    * 在目标类中添加一些新的方法和属性

Spring中的切面类型

  • Advisor : Spring中传统切面.
    * Advisor:都是有一个切点和一个通知组合.
    * Aspect:多个切点和多个通知组合.

  • Advisor : 代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)
  • PointcutAdvisor : 代表具有切点的切面,可以指定拦截目标类哪些方法(带有切点的切面,针对某个方法进行拦截)
  • IntroductionAdvisor : 代表引介切面,针对引介通知而使用切面(不要求掌握)

Spring的AOP的开发

针对所有方法的增强:(不带有切点的切面)

  • 第一步:导入相应jar包.
    * spring-aop-3.2.0.RELEASE.jar
    * com.springsource.org.aopalliance-1.0.0.jar
  • 第二步:编写被代理对象:
    * CustomerDao接口
package cn.spring3.demo3;
/*接口类
*/
public interface CustomerDao {public void add();public void update();public void delete();public void find();
}

* CustoemrDaoImpl实现类

package cn.spring3.demo3;/*** @author NOP* 针对所有方法的增强*/
public class CustomerDaoImpl implements CustomerDao {public void add() {System.out.println("添加客户");}public void delete() {System.out.println("删除客户");}public void find() {System.out.println("查询客户");}public void update() {System.out.println("修改客户");}
}
  • 第三步:编写增强的代码:
package cn.spring3.demo3;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
/*** @author NOP* 前置增强*/
public class MyBeforeAdvice implements MethodBeforeAdvice{/*** method:执行的方法* args:参数* target:目标对象*/public void before(Method method, Object[] args, Object target)throws Throwable {// TODO Auto-generated method stubSystem.out.println("前置增强...");}
}
  • 第四步:生成代理:(配置生成代理:)

* 生成代理Spring基于ProxyFactoryBean类.底层自动选择使用JDK的动态代理还是CGLIB的代理.
* 属性:
target : 代理的目标对象
proxyInterfaces : 代理要实现的接口
如果多个接口可以使用以下格式赋值
<list>
<value></value>
....
</list>
proxyTargetClass : 是否对类代理而不是接口,设置为true时,使用CGLib代理
interceptorNames : 需要织入目标的Advice
singleton : 返回代理是否为单实例,默认为单例
optimize : 当设置为true时,强制使用CGLib

<!-- 传统方式代理 --><!-- 不带有切点的切面 --><!-- 目标对象 --><bean id="customerDao" class="cn.spring3.demo3.CustomerDaoImpl"></bean><!-- 定义增强 --><bean id="beforeAdvice" class="cn.spring3.demo3.MyBeforeAdvice"></bean><!-- Srping配置增强代理 --><bean id="customerDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><!-- 设置目标对象 --><property name="target" ref="customerDao"></property><!-- 设置实现的接口 ,value中写接口的全路径--><property name="proxyInterfaces" value="cn.spring3.demo3.CustomerDao"></property><!-- 需要使用的value:要的名称 --><property name="interceptorNames" value="beforeAdvice"></property><!-- 强制使用CGLib代理 <property name="optimize" value="true"/>--></bean><!-- 不带有切点的切面 -->

第五步:编写测试类

package cn.spring3.demo3;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4Cla***unner;@RunWith(SpringJUnit4Cla***unner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest3 {@Autowired//@Qualifier("customerDao")//注入的真实的对象,必须注入代理对象@Qualifier("customerDaoProxy")private CustomerDao customerDao;/** 不带有切点的切面*/@Testpublic void demo1(){customerDao.add();customerDao.delete();customerDao.find();customerDao.update();}
}
测试结果:
前置增强...
添加客户
前置增强...
删除客户
前置增强...
查询客户
前置增强...
修改客户

带有切点的切面:(针对目标对象的某些方法进行增强)

  • PointcutAdvisor 接口:

    • DefaultPointcutAdvisor 最常用的切面类型,它可以通过任意Pointcut和Advice 组合定义切面
    • RegexpMethodPointcutAdvisor 构造正则表达式切点切面

第一步:创建被代理对象.
* OrderDao

package cn.spring3.demo4;
/*** @author NOP* 目标对象*/
public class OrderDao {public void add() {// TODO Auto-generated method stubSystem.out.println("添加订单");}public void delete() {// TODO Auto-generated method stubSystem.out.println("删除订单");}public void find() {// TODO Auto-generated method stubSystem.out.println("查询订单");}public void update() {// TODO Auto-generated method stubSystem.out.println("修改订单");}
}

第二步:编写增强的类:

package cn.spring3.demo4;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/*** @author NOP 增强的类 使用的是环绕*/
public class MyAroundAdvice implements MethodInterceptor {public Object invoke(MethodInvocation methodInvocation) throws Throwable {// TODO Auto-generated method stubSystem.out.println("环绕前增强。。。");Object result = methodInvocation.proceed();// 执行目标对象的方法System.out.println("环绕后增强。。。");return result;}
}

第三步:生成代理:

<!-- 带有切点的切面 --><!-- 目标对象 --><bean id="orderDao" class="cn.spring3.demo4.OrderDao"></bean><!-- 定义增强 --><bean id="aroundAdvice" class="cn.spring3.demo4.MyAroundAdvice"></bean><!-- ********************************定义切点*************** --><bean id="mypointcutAdviesor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><!--定义正则表达式,规定哪些方法执行拦截  pattern是一个方法patterns是多个方法--><!-- <property name="pattern" value=".*"/> 这个正则是所有--><!--<property name="pattern" value="cn\.spring3\.demo4\.OrderDao\.delete.*"/>--><!--<property name="pattern" value=".*add.*"/>--><property name="patterns" value=".*add.*,.*update.*"/><!-- 应用增强 --><property name="advice" ref="aroundAdvice"/></bean><!-- ********************************定义切点*************** --><!-- 定义生成代理对象 --><bean id="orderDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><!-- 设置目标对象 --><property name="target" ref="orderDao"></property><!-- 针对类的代理--><property name="proxyTargetClass" value="true"></property><!-- 在目标上应用增强 --><property name="interceptorNames" value="mypointcutAdviesor"></property></bean><!-- 带有切点的切面 -->

第四步:编写测试类

package cn.spring3.demo4;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4Cla***unner;@RunWith(SpringJUnit4Cla***unner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest1 {@Autowired//@Qualifier("orderDao")//注入的真实的对象,必须注入代理对象@Qualifier("orderDaoProxy")private OrderDao orderDao;/** 带有切点的切面*/@Testpublic void demo1(){orderDao.add();orderDao.delete();orderDao.find();orderDao.update();}
}
测试结果:
环绕前增强。。。
添加订单
环绕后增强。。。
删除订单
查询订单
环绕前增强。。。
修改订单
环绕后增强。。。

自动代理

  • 前面的案例中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大

  • 自动创建代理(*****基于后处理Bean.在Bean创建的过程中完成的增强.生成Bean就是代理.)
  • BeanNameAutoProxyCreator 根据Bean名称创建代理
  • DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理
    • * AnnotationAwareAspectJAutoProxyCreator 基于Bean中的AspectJ 注解进行自动代理

自动方式代理没有切点切面的增强

<!-- 自动方式代理没有切点切面的增强 --><!-- 目标对象 --><bean id="customerDao" class="cn.spring3.demo3.CustomerDaoImpl"></bean><bean id="orderDao" class="cn.spring3.demo4.OrderDao"></bean><!-- 定义增强 --><bean id="beforeAdvice" class="cn.spring3.demo3.MyBeforeAdvice"></bean><bean id="aroundAdvice" class="cn.spring3.demo4.MyAroundAdvice"></bean><!-- 自动代理:按名称的代理 基于后处理Bean,后处理Bean不需要配置ID --><bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><property name="beanNames" value="*Dao"/><property name="interceptorNames" value="beforeAdvice"/></bean>

编写测试类:

package cn.spring3.demo5;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4Cla***unner;
import cn.spring3.demo3.CustomerDao;
import cn.spring3.demo4.OrderDao;/*** @author NOP* 自动方式代理没有切点切面的增强*/
@RunWith(SpringJUnit4Cla***unner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class SpringTest {@Autowired@Qualifier("orderDao")//不用注入代理,因为类已经是代理了private OrderDao orderDao;@Autowired@Qualifier("customerDao")private CustomerDao customerDao;@Testpublic void demo1(){orderDao.add();orderDao.delete();customerDao.find();customerDao.update();}
}
测试结果:
前置增强...
添加订单
前置增强...
删除订单
前置增强...
查询客户
前置增强...
修改客户

自动方式代理 有切点切面的增强

<!-- 自动方式代理 有切点切面的增强 --><!-- 目标对象 --><bean id="customerDao" class="cn.spring3.demo3.CustomerDaoImpl"></bean><bean id="orderDao" class="cn.spring3.demo4.OrderDao"></bean><!-- 定义增强 --><bean id="beforeAdvice" class="cn.spring3.demo3.MyBeforeAdvice"></bean><bean id="aroundAdvice" class="cn.spring3.demo4.MyAroundAdvice"></bean><!-- 定义切点 --><bean id="mypointcutAdviesor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><!--定义正则表达式,规定哪些方法执行拦截  --><property name="patterns" value=".*add.*,.*update.*"/><!-- 应用增强 --><property name="advice" ref="beforeAdvice"/></bean><!-- 自动代理:按名称的代理 基于后处理Bean,后处理Bean不需要配置ID --><bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><property name="beanNames" value="*Dao"/><property name="interceptorNames" value="mypointcutAdviesor"/></bean>

编写测试类:

package cn.spring3.demo5;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4Cla***unner;import cn.spring3.demo3.CustomerDao;
import cn.spring3.demo4.OrderDao;/*** @author NOP* 自动方式代理 有切点切面的增强*/
@RunWith(SpringJUnit4Cla***unner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class SpringTest_1 {@Autowired@Qualifier("orderDao")private OrderDao orderDao;@Autowired@Qualifier("customerDao")private CustomerDao customerDao;@Testpublic void demo1(){orderDao.add();orderDao.delete();orderDao.update();orderDao.find();customerDao.add();customerDao.delete();customerDao.update();customerDao.find();}
}
测试结果:
前置增强...
添加订单
删除订单
前置增强...
修改订单
查询订单
前置增强...
添加客户
删除客户
前置增强...
修改客户
查询客户

区分基于ProxyFactoryBean的代理与自动代理区别?
***** ProxyFactoryBean:先有被代理对象,将被代理对象传入到代理类中生成代理.
自动代理基于后处理Bean.在Bean的生成过程中,就产生了代理对象,把代理对象返回.生成Bean已经是代理对象.

转载于:https://blog.51cto.com/4534309/2112427

Spring中的AOP(8)相关推荐

  1. 一文读懂Spring中的AOP机制

    一.前言 这一篇我们来说一下 Spring 中的 AOP 机制,为啥说完注解的原理然后又要说 AOP 机制呢? 1.标记日志打印的自定义注解 @Target({ElementType.METHOD}) ...

  2. 动态代理——》AOP —— Spring 中的 AOP||AOP 相关术语||学习 spring 中的 AOP 要明确的事

    AOP 概述 什么是 AOP       AOP:全称是 Aspect Oriented Programming 即:面向切面编程 AOP 的作用及优势 作用: 在程序运行期间,不修改源码对已有方法进 ...

  3. Spring中的AOP(三)——基于Annotation的配置方式(一)

    为什么80%的码农都做不了架构师?>>>    AspectJ允许使用注解用于定义切面.切入点和增强处理,而Spring框架则可以识别并根据这些注解来生成AOP代理.Spring只是 ...

  4. spring中的aop术语和细节

    Spring中AOP的细节 说明 我们学习spring的aop,就是通过配置的方式 AOP相关术语 Joinpoint(连接点): 所谓连接点是指那些被拦截到的点.在spring中,这些点指的是方法, ...

  5. 手动实现SPring中的AOP(1)

    Spring中的AOP是基于JDK的API动态的在内存中创建代理对象的.所以这里先介绍一些设计模式之----代理模式: a)         代理模式的定义:代理(Proxy)模式是一种提供对目标对象 ...

  6. java day59【 AOP 的相关概念[理解] 、 Spring 中的 AOP[掌握] 、 Spring 整合 Junit[掌握] 】...

    第1章 AOP 的相关概念[理解] 1.1AOP 概述 1.1.1 什么是 AOP 1.1.2 AOP 的作用及优势 1.1.3 AOP 的实现方式 1.2AOP 的具体应用 1.2.1 案例中问题 ...

  7. Spring 中的AOP的通知类型的示例(xml)

    个人博客:https://suveng.github.io/blog/​​​​​​​ Spring 中的AOP的通知类型的示例 AOP中的通知类型(advice)一共有五中: around advic ...

  8. Spring中的AOP切面编程的三种实现方式

    文章目录 Spring中的AOP切面编程的三种实现方式 1.最基本AOP的实现 a.引入jar包 b.编写通知类,这里以后置通知和环绕通知类为例子进行说明 c.在SpringIOC容器中配置 d.测试 ...

  9. java学习day40(Spring)spring中的aop和基于XML以及注解的AOP配置

    第1章 AOP 的相关概念[理解] 1.1AOP 概述 1.1.1 什么是 AOP AOP :全称是 Aspect Oriented Programming 即:面向切面编程. 简单的说它就是把我们程 ...

  10. 【spring 5】AOP:spring中对于AOP的的实现

    在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现. 一.采用Annotation方式 首先引入jar包:aspectjrt.jar && ...

最新文章

  1. hdu 1166 敌兵布阵(树状数组)
  2. day 05 python基础
  3. 云游戏是大厂的“游戏”之腾讯云云游戏指南
  4. 背账100万,不付利息不用还钱,银行套路好深
  5. linux系统的层次结构,关于Linux操作系统层次结构分析
  6. linux加密框架 crypto 算法crypto_register_alg的注册流程
  7. osgi框架 android,基于OSGi的Android应用模块动态加载框架设计与实现
  8. ❤️六W字《计算机基础知识》(八)(建议收藏)❤️
  9. 搭建vue脚手架_webpack搭建vue脚手架
  10. spring boot(5)---RestTemplate请求HTTP(1)
  11. unity创建草地_Unity3D研究院之构建游戏地形的基本元素(五)
  12. 命令行基础-tar命令详解
  13. Pycharm处理 E501 line too long 警告
  14. python 前缀和总结
  15. 人工智能NLP项目_深度学习和神经网络(1)
  16. 折腾了好久 ORA-00904: : 无效的标识符
  17. win10防火墙推荐设置来保护计算机,win10提示windows防火墙没有法更改某些设置如何办?...
  18. ceph monitor 选举leader和peon的过程
  19. 动画特效十五:网易新闻之头部导航切换效果
  20. 音视频技术开发周刊 | 277

热门文章

  1. 谈谈原子变量与锁的性能比较
  2. Angular开发实践(五):深入解析变化监测
  3. EJB3.0 Timer
  4. Ubuntu安装Chromium
  5. 如何访问个人邮箱中的未读邮件
  6. 《魔兽世界插件》教程---21点扑克游戏 Blackjack
  7. CGAffineTransform 放射变换
  8. linux中安装,编译时调用,运行时调用,更新共享库
  9. struts读常量顺序
  10. Android Ndef Message解析