SpringAop源码见解(上)

Aop相信大家都熟悉一二了,实际上AOP是一种编程思想,横向抽取,纵向重复讲的就是这种思想。

其中需要理解的概念有:

切面:即我们需要操作的一个类(整体概念)

连接点:即我们需要增强的方法,入口

切入点:增强后的方法

代理对象:即需要增强的对象

通知:即方法需要增强的部分,包括前置通知,后置通知,正常返回通知,异常放回通知,环绕通知5种

织入:即将通知加入要增强的方法的动作

首先正式讲之前讲pointcut的知识:

pointcut:即切入点的范围表达式,他在用注解的时候可以通过建立一个空方法,比如public void pointcut1(){};

那么在使用注解时切入点的表达式使用可以为@before("pointcut1()");poitcut的表达式规则为:* org.sunfork.*.*(..);这个表达式的意思为:第一个* 代表方法的权限修饰符,如果为*则不限制,org.sunfork.*.*则表示在org.sunfork下的所有类的所有方法以及子包下的所有类所有方法,(..)则代表的是不限制方法的传参。pointcut还有几种通配方式。* org.sunfork.*.*Service表示的则是当前包以及所有包的以Service结尾的所有类的所有方法,如OrderService.还有一种及时在设计注解框架设计时常用到的表达式:@annotation(com.sunfork.security.HasPermision)表示的则是所有被HasPermision注解修饰的方法都将是连接点。

Spring实现这种方法分为XML和注解两种方式:Xml配置标签有

<aop:config>

<aop:pointcut id="pointcut" exection="*  org.sunfork.aop.*(..)"><aop:pointcut>

<aop:aspect  id=""  pointcut-ref="pointcut">

<aop:before id="" pointcut-ref="pointcut"></aop:before>

<aop:after id=""  pointcut-ref="pointcut"></aop:after>

<aop:around id=""  pointcut-ref="pointcut"></aop:around>

<aop:after-throwing id=""  pointcut-ref="pointcut"></aop:after-throwing>

<aop:after-return id=""  pointcut-ref="pointcut"></aop:after-return>

</aop:aspect>

</aop:config>

Spring实现aop原理是Cglib代理和JDK动态代理。spring会根据需要增强的类的是否有接口,若没有则采用Cglib面向实现类代理,若有实现的接口则采用jdk自带的动态代理。

接下来进入Spring的AOP具体源码实现:

Spring的AOP入口是一个AopNameSpaceHandler实现类,该接口类实现的接口是SPring提供的NameSpaceHandlerSupport接口,因为切面也是采用SpringIOC注入,那么必然是在将切面注入容器时做了一些的特殊的操作。那么我们又得追溯到IOC实现原理了。IOC的过程无非是载入,注册等过程。在XML解析时,Spring的核心类时一个DefaultBeanfinitionDocumentReader:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();

        for(int i = 0; i < nl.getLength(); ++i) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element)node;
                if (delegate.isDefaultNamespace(ele)) {
                    this.parseDefaultElement(ele, delegate);
                } else {
                    delegate.parseCustomElement(ele);
                }
            }
        }
    } else {
        delegate.parseCustomElement(root);
    }

}在这段代码中,我们的可以看到Spring在解析时,分为官方默认的标签,即alias,beans,import,bean这四个标签是调用官方的parse,自定义标签则包括

猜你喜欢

转载自blog.csdn.net/baidu_41654449/article/details/80546033