文档章节

Spring AOP

OrangeJoke
 OrangeJoke
发布于 2017/08/17 14:52
字数 1037
阅读 24
收藏 1

AOP

面向切面编程

AspectJ

intro to aspectJ

Spring AOP Design

AOP面向切面编程是通过代理对象来实现的,和拦截器是不是有点像,最主要的区别就是PointCut,来看看接口设计:

public interface Pointcut {

	/**
	 * Return the ClassFilter for this pointcut.
	 * @return the ClassFilter (never {@code null})
	 */
	ClassFilter getClassFilter();

	/**
	 * Return the MethodMatcher for this pointcut.
	 * @return the MethodMatcher (never {@code null})
	 */
	MethodMatcher getMethodMatcher();
}

Spring 整合AspectJ,使用了AspectJ对切面的定义,同时支持自己的xml space定义切面等信息,AspectJ还是支持weaving(compiling,loading)阶段。

Spring的整合方式是提供spring自己的weaving方式,动态代理,运行时刻,并协同spring ioc进行工作,满足绝大多数企业应用场景。 当然spring也支持独立使用AspectJ,使用原生的weaving方式。

spring的设计哲学,包容并可扩展。 spring aop

Spring AOP Proxy

Spring AOP 的实现方式是为目标对象生成代理对象。 Spring AOP 框架对 AOP 代理类的处理原则是:如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类——不过这个选择过程对开发者完全透明、开发者也无需关心,CGLIB 底层使用ASM。

Proxy CGLIB

// 拦截器类
public class AroundAdvice implements MethodInterceptor 
{ 
    public Object intercept(Object target, Method method , Object[] args, MethodProxy proxy) 
throws java.lang.Throwable 
{ 
    System.out.println("执行目标方法之前,模拟开始事务 ..."); 
    // 执行目标方法,并保存目标方法执行后的返回值
    Object rvt = proxy.invokeSuper(target, new String[]{"被改变的参数"}); 
    System.out.println("执行目标方法之后,模拟结束事务 ..."); 
    return rvt + " 新增的内容"; 
} 
}


//接下来程序提供一个 ChineseProxyFactory 类,这个 ChineseProxyFactory 类会通过 CGLIB 来为 Chinese 生成代理类
public class ChineseProxyFactory 
{ 
    public static Chinese getAuthInstance() 
        { 
            Enhancer en = new Enhancer(); 
            // 设置要代理的目标类
            en.setSuperclass(Chinese.class);
            // 设置要代理的拦截器
            en.setCallback(new AroundAdvice());
            // 生成代理类的实例 
            return (Chinese)en.create();
        } 
}

Proxy Jdk

Spring AOP 会动态选择使用 JDK 动态代理、CGLIB 来生成 AOP 代理,如果目标类实现了接口,Spring AOP 则无需 CGLIB 的支持,直接使用 JDK 提供的 Proxy 和 InvocationHandler 来生成 AOP 代理即可

//Proxy 编程是面向接口的。下面我们会看到,Proxy 并不负责实例化对象,和 Decorator 模式一样,要把 Account定义成一个接口,然后在 AccountImpl里实现 Account接口,接着实现一个 InvocationHandlerAccount方法被调用的时候,虚拟机都会实际调用这个 InvocationHandler的 invoke方法

class SecurityProxyInvocationHandler implements InvocationHandler { 
    private Object proxyedObject; 
    public SecurityProxyInvocationHandler(Object o) { 
        proxyedObject = o; 
    } 
        
    public Object invoke(Object object, Method method, Object[] arguments) 
        throws Throwable {             
        if (object instanceof Account && method.getName().equals("opertaion")) { 
            SecurityChecker.checkSecurity(); 
        } 
        return method.invoke(proxyedObject, arguments); 
    } 
}

//在应用程序中指定 InvocationHandler生成代理对象
public static void main(String[] args) { 
    Account account = (Account) Proxy.newProxyInstance( 
        Account.class.getClassLoader(), 
        new Class[] { Account.class }, 
        new SecurityProxyInvocationHandler(new AccountImpl()) 
    ); 
    account.function(); 
}

关于Spring Aop 的具体实现,这里有源码解析spring aop 源码解析

面试的时候常会被问及的一个问题,如果一个类里面的两个方法都被增强了,method1 调用 method2 的时候,method2 会被增强吗? 其实这个问题很简单,AOP只是在使用proxy类对method1做了增强,然后会调用target的method1方法,然后target.method1 invoke target.method2. 所以method2是没有被增强的。

为什么private方法不能使用AOP?
因为两种实现方式都不能代理private方法,cglib通过继承父类的方式,不能访问父类private方法。

Spring Transaction

我们知道Spring 的@Transaction 是通过切面实现的,然后在事务嵌套过程中会有上面我们提到的类似的问题,那事务里面是怎么解决的呢。
通过属性propagation 来控制事务的传播,所以需要理解这个才不会迷惑.

参考

https://vimeo.com/52990474

https://www.ibm.com/developerworks/cn/java/j-lo-asm30/

https://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/index.html

© 著作权归作者所有

OrangeJoke
粉丝 40
博文 57
码字总数 39192
作品 0
江北
高级程序员
私信 提问
Spring之 Aspect Oriented Programming with Spring

1. Concepts Aspect-Oriented Programming (AOP) complements OOP by providing another way of thinking about program structure. While OO decomposes applications into a hierarchy of ......

leodaxin
2018/07/29
0
0
主键不是id的实体使用insertUseGeneratedKeys方法问题

@Liuzh_533 你好,想跟你请教个问题: 看了你在 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvide......

rexxx
2017/05/27
829
1
Spring中的AOP(二)——AOP基本概念和Spring对AOP的支持

AOP的基本概念 AOP从运行的角度考虑程序的流程,提取业务处理过程的切面。AOP面向的是程序运行中的各个步骤,希望以更好的方式来组合业务逻辑的各个步骤。AOP框架并不与特定的代码耦合,AOP...

摆渡者
2014/03/17
2.1K
3
Spring 2.0 的AOP介绍及其通知类型

Spring 2.0的AOP 在Spring 2.0中最激动人心的增强之一是关于Spring AOP,它变得更加便于使用而且更加强大,主要是通过复杂而成熟的AspectJ语言的支持功能来实现,而同时保留纯的基于代理的J...

小星星程序员
2014/08/15
308
0
最最简单的spring及AOP实例

一、简单的spring实现(annotation方式) bean类 测试类: 运行结果: (xml方式) bean类 xml配置文件applicationContext.xml(放在包com.hello下) 测试类: 二、注解方式实现aop(需要导入...

wangxuwei
2017/10/24
210
0

没有更多内容

加载失败,请刷新页面

加载更多

Elasticsearch入门 - 功能特点介绍

开篇 上一篇主要简单介绍了下 Elasticsearch(简称: ES) 的官方概念,本篇主要介绍 Elasticsearch 的主要功能特点以及使用场景,文章内容是总结多篇文章及视频资料整理出来。 功能 1. 分布...

nimo10050
46分钟前
72
0
六、Spring Cloud之配置中心config

前言 前面我们讲了微服务的注册中心、负载均衡、熔断处理、网管服务。接下来我们讲配置中心,为什么要用配置中心呢? 其实我们接触一段时间就可以发现,我们的项目还是非常多的,每个项目都有...

quellanan2
47分钟前
33
0
在Android的EditText视图中允许多行?

如何在Android的EditText视图中允许多行? #1楼 这对我有用 ,实际上这两个属性很重要: inputType和lines 。 此外,您可能需要一个滚动条,下面的代码显示了如何制作一个: <EditText ...

技术盛宴
50分钟前
25
0
分享自己写的JS版日期格式化和解析工具类,绝对好用!

前言 本来想模仿Java里面的SimpleDateFormat()对象的,但是感觉这样用起来不方便,所以还是直接写成单独的方法算了。 原文链接 日期格式化 2.1. 使用说明 formatDate(date, fmt),其中fmt支持...

SuShine
今天
42
0
快递鸟api物流查询接口实现订阅物流轨迹单号查询功能对接调用

背景: 分享一篇关于在电商系统中同步物流轨迹到本地服务器的文章,当前方案使用了快递鸟集成api做为数据来源接口,这个接口是免费使用的,不过提供的功能还是非常强大的,有专门的售后维护团...

程序的小猿
今天
46
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部