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,自定义标签则包括