一、通过代理工厂模式配置通知

①、前置通知、后置通知:

定义某接口:ISomeService,并自定义方法

  1. public interface ISomeService {
  2. public void tran() throws Exception;
  3. public void log();
  4.  
  5. }

定义类 实现该接口,并重写方法:  

  1. public class SomeService implements ISomeService{
  2.  
  3. public void tran() throws Exception{
  4. System.out.println("开启事务!!");
  5.  
  6. }
  7.  
  8. public void log() {
  9. System.out.println("记录日志!!");
  10. }

定义前置通知类,并实现MethodBeforeAdvice该接口  

  1. public class MyBefore implements MethodBeforeAdvice{
  2.  
  3. public void before(Method arg0, Object[] arg1, Object arg2)
  4. throws Throwable {
  5. System.out.println("==before==");
  6.  
  7. }

定义后置通知类,并实现AfterReturningAdvice该接口  

  1. public class MyAfter implements AfterReturningAdvice{
  2.  
  3. public void afterReturning(Object arg0, Method arg1, Object[] arg2,
  4. Object arg3) throws Throwable {
  5. System.out.println("==after==");
  6.  
  7. }

配置Spring配置文件applicationContext.xml:

代理工厂:ProxyFactoryBean

测试类:

实现效果:


② 环绕通知  MethodInterceptor

环绕增强在目标方法的前后都可以织入增强处理。环绕增强是功能最强大的强大处理。Spring把目标方法的控制权全部交给了他。在环绕增强处理中,可以获取或修改目标方法的参数、返回值、可以对它进行异常处理,甚至可以决定目标方法是否执行。 

配置Spring文件:

  1. <!-- 环绕增强 -->
  2. <bean id="some" class="cn.happy.entity.SomeService"></bean>
  3.  
  4. <bean id="arround" class="cn.happy.arround.MyInterceptor"></bean>
  5.  
  6. <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
  7. <property name="target" ref="some"></property>
  8. <property name="interceptorNames" value="arround"></property>
  9. </bean>

实现效果:

通过MethodInterceptor接口实现了环绕增强。该接口要求实现invoke()方法,其参数MethodInvocation不但封装目标方法及其参数组,还封装了被代理目标对象。通过proceed()方法可以调用目标对象的相应方法,从而实现对目标方法的完全控制!


③异常通知:

特点是在目标方法抛出异常时织入增强处理。通过ThrowsAdvice接口实现异常抛出增强,但ThrowsAdvice接口中并没有定义任何方法,但是我们在定义异常抛出的增强方法时必须遵守以下方法签名:  

  1. void afterThrowing([Method method,Object[]arguments,Object target,] Throwable ex)

实现类出现异常情况下:

Spring配置文件:

  1. <!-- 异常通知 -->
  2. <bean id="some" class="cn.happy.entity.SomeService"></bean>
  3.  
  4. <bean id="throws" class="cn.happy.throwsAdvice.MyThrows"></bean>
  5.  
  6. <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
  7. <property name="target" ref="some"></property>
  8. <property name="interceptorNames" value="throws"></property>
  9. </bean>

测试类:  

若将异常抛给上级处理,则在控制台通过,单测报错,若将异常手动抛出,则相反

  1. @Test
  2. public void proxyTest(){
  3. ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
  4. ISomeService ser=(ISomeService) ctx.getBean("factory");
  5. //ser.tran();
  6. try {
  7. ser.tran();
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }
  11. ser.log();
  12.  
  13. }

 


二、顾问Advisor

顾问Advisor是Spring提供的另一种切面。其可以完成更为复杂的切面织入功能。PointcutAdvisor是顾问的一种,可以指定具体的切入点。顾问将通知进行了包装,会根据不同的通知类型,在不同的时间点,将切面织入到不同的切入点。
PointcutAdvisor接口有两个较为常用的实现类:
*:NameMatchMethodPointcutAdvisor 名称匹配方法切入点顾问
*:  RegexpMethodPointcutAdvisor 正则表达式匹配方法切入点顾问
<property name="pattern" value=".*do.*"></property> 表示方法全名(包名,接口名,方法名)
运算符名称意义:
.    点号 表示任意单个字符
+   加号 表示前一个字符出现一次或者多次
*    星号 表示前一个字符出现0次或者多次

如何实现:

同理:定义接口和实现类,并自定义方法。以及前置增强的类。关键点在Spring配置文件

①名称匹配方法切入点顾问

② 正则表达式匹配方法切入点顾问


三、自动代理生成器

注意:默认Advisor自动代理生成器,切面只能是顾问,对所有的对象都增强

两种实现方式:

① 默认Advisor自动代理生成器 DefaultAdvisorAutoProxyCreator

② BeanName自动代理生成器 BeanNameAutoProxyCreator

在这里 无需配置代理工厂bean,测试类getBean()取的id是配置文件的被代理对象

切面只能是顾问的情况下:

实现效果:

既可以是通知也可以是顾问的情况下:

实现效果:

测试类:

  1. public class Test01 {
  2. @Test
  3. public void proxyTest(){
  4. ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
  5. ISomeService ser=(ISomeService) ctx.getBean("some");
  6. ser.tran();
  7. ser.log();
  8.  
  9. }

 


四、Spring的经典AOP配置方案、使用的是Aspectj第三方框架,实现了AOP思想。注解配置的AOP,纯POJO <aop:config>

具体步骤:
① 在项目中添加SpringAOP相关的JAR文件

②使用注解定义前置增强和后置增强实现日志功能

③编写Spring配置文件,织入注解定义的增强

④编写代码获取带有增强处理的业务对象

核心JAR包:

实现思路:

1、定义接口实现类,并重写该方法

  1. public interface ISomeService {
  2. public void list();
  3. }
  1. public class SomeService implements ISomeService{
  2.  
  3. public void list() {
  4. System.out.println("SomeService.list()");
  5. }
  6.  
  7. }

2、通过注解实现增强,自定义类  

使用@Aspect注解将该类定义为切面,并且使用@Before注解将该方法定义为前置增强,增强定义完后,就可以在Spring配置文件中织入使用注解定义的增强了

  1. @Aspect
  2.  
  3. public class MyAspectj {
  4.  
  5. @Before(value = "execution(* *..service.*.*(..))")
  6.  
  7. public void MyBeforeAdvice(){
  8. System.out.println("==before==");
  9. }
  10. }

3、Spring配置文件

4、进行测试:

  1. public class Test01 {
  2. @Test
  3. public void proxyTest(){
  4. ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
  5. ISomeService ser=(ISomeService) ctx.getBean("some");
  6. ser.list();
  7.  
  8. }

实现效果: 


※※※补充点:

切入点表达式:
 execution(【modifiers-pattern?】 访问修饰符
 ret-type-pattern 返回值类型
【declaring-type-pattern?】 全限定性类名
 name-pattern(param-pattern) 方法名(参数名) 包名.类型名.方法名
【throws-pattern?】) 抛出异常类型

public void doLog(String log){

}

切入点表达式要匹配的对象就是目标方法的方法名。所以,execution表达式中明显就是方法的签名。

注意:表达式中加[]的部分表示可省略部分,各部分间用空格分开。在其中可以使用以下符号:
符号意义:
*    0至多个任意字符
..    用在方法参数中,表示任意多个参数
      用在包名后,表示当前包及其子包路径
+    用在类名后,表示当前类及其子类
      用在接口后,表示当前接口及其实现类
案例:
execution(public * *(..)) 指定切入点为:任意公共方法
execution(* set*(..)) 指定切入点为:任何一个以"set"开始的方法

Spring AOP深入剖析的更多相关文章

  1. Spring AOP 深入剖析

    AOP是Spring提供的关键特性之一.AOP即面向切面编程,是OOP编程的有效补充.使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统.从而避免了在业务逻 ...

  2. [转载]Spring AOP 深入剖析

    转载自 http://www.cnblogs.com/digdeep/p/4528353.html 多谢@digdeep AOP是Spring提供的关键特性之一.AOP即面向切面编程,是OOP编程的有 ...

  3. Spring AOP 实现原理与 CGLIB 应用

    https://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/ AOP(Aspect Orient Programming),也就是面向 ...

  4. Spring AOP 实现原理与 CGLIB 应用--转

    AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 ...

  5. spring AOP 之一:spring AOP功能介绍

    一.AOP简介 AOP:是一种面向切面的编程范式,是一种编程思想,旨在通过分离横切关注点,提高模块化,可以跨越对象关注点.Aop的典型应用即spring的事务机制,日志记录.利用AOP可以对业务逻辑的 ...

  6. 【转】Spring AOP 实现原理与 CGLIB 应用

    AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 ...

  7. spring AOP详解四

    AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 ...

  8. Spring源码剖析6:Spring AOP概述

    原文出处: 五月的仓颉 我们为什么要使用 AOP 前言 一年半前写了一篇文章Spring3:AOP,是当时学习如何使用Spring AOP的时候写的,比较基础.这篇文章最后的推荐以及回复认为我写的对大 ...

  9. Spring源码剖析7:AOP实现原理详解

    前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...

随机推荐

  1. 疯狂Android讲义 - 学习笔记(七)

    第8章 Android数据存储与IO  Java IO的数据存储可以移植到Android应用开发上来,Android系统还提供了一些专门的IO API. Android系统内置了SQLite数据库,S ...

  2. linux 下添加库的加载路径的方式

    linux 下有两种添加加载库路径的方式: 1.修改环境变量: export LD_LIBRARY_PATH=path_name 2.修改配置文件 修改 /etc/ld.so.conf 的内容在最后添 ...

  3. 学习.NET是因为热爱 or 兴趣 or 挣钱?

    看到最近园子里掀起了“.NET快不行了”.“.NET工资太低了”.“转行做XX”等一系列之风,不由得想说点什么,我只是基于自己的观点,你认同或者不认同,我就是这样认为,无所谓对与错,写文章就是为了交流 ...

  4. Netty(四)分隔符与定长解码器的使用

    TCP以流的形式进行数据传输,上层的应用协议为了对消息进行划分,往往采用如下的4种方式. (1)消息长度固定,累计读到长度总和为定长len的报文后,就认为读取到了一个完整的消息:然后重新开始读取下一个 ...

  5. JavaScript 变量声明提前

    <JavaScript权威指南>中指出:JavaScript变量在声明之前已经可用,JavaScript的这个特性被非正式的称为声明提前(hoisting),即JavaScript函数中声 ...

  6. Menu创建菜单

    菜单是用户界面中最常见的元素之一,使用非常频繁,在Android中,菜单被分为如下三种,选项菜单(OptionsMenu).上下文菜单(ContextMenu)和子菜单(SubMenu),今天这讲是O ...

  7. 设置导航栏nav全透明

    设置导航栏nav全透明 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #ffffff } span.s1 { } ...

  8. Android高效计算——RenderScript(一)

    高效计算——RenderScript RenderScript是安卓平台上很受谷歌推荐的一个高效计算平台,它能够自动把计算任务分配到各个可用的计算核心上,包括CPU,GPU以及DSP等,提供十分高效的 ...

  9. Picasso设置圆角

    package liu.roundimagedemo.view; import android.graphics.Bitmap; import android.graphics.BitmapShade ...

  10. configure Git to accept a particular self-signed server certificate for a particular https remote

    get the self signed certificate put it into some (e.g. ~/git-certs/cert.pem) file set git to trust t ...