您的位置:首页 > 编程语言 > ASP

简单直白的去理解AOP,了解Spring AOP,使用 @AspectJ - 读书笔记

2014-03-28 18:37 423 查看
AOP = Aspect Oriental Programing 面向切面编程

文章里不讲AOP术语,什么连接点、切点、切面什么的,这玩意太绕,记不住也罢。旨在以简单、直白的方式理解AOP,理解Spring AOP, 应用 @AspectJ。

什么是AOP?

Spring AOP 实现机制

使用Spring AOP,并通过xml配置(这个稍微看看就行了,你不一定用它)

使用@AspectJ (未完成)

1、什么是AOP?

方法1方法2方法3
AAA
代码x代码y代码z
BBB
从纵向看,方法1、2、3 都执行了相同的A、B代码,这样重复代码是很无聊的。

一个典型的场景就是:开启事务,更新表里数据,提交事务; 开启事务,删除表里数据,提交事务。

所以我们从横向来,把重复代码抽取出来,变为

AAA
方法1(代码x)方法2(代码y)方法3(代码z)
BBB
AOP希望将A、B 这些分散在各个业务逻辑中的相同代码,通过横向切割的方式抽取到一个独立的模块中,还业务逻辑类一个清新的世界。

当然,将这些重复性的横切逻辑独立出来很容易,但是如何将独立的横切逻辑 融合到 业务逻辑中 来完成和原来一样的业务操作,这是事情的关键,也是AOP要解决的主要问题。

2.Spring AOP 实现机制

Spring AOP使用动态代理技术在运行期织入增强的代码,使用了两种代理机制,一种是基于JDK的动态代理,另一种是基于CGLib的动态代理。

织入、增强 是AOP的两个术语,织入增强的代码简单点就是在你的代码上插入另一段代码。

JDK动态代理主要涉及到java.lang.reflect包中的两个类:Proxy 和 InvocationHandler(接口)。

直接上代码

package com.ycp.framework.test.proxyPattern.sample2;

import java.lang.reflect.Method;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionInterceptor;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;

public class AddAdvisor extends StaticMethodMatcherPointcutAdvisor {

//StaticMethodMatcherPointcutAdvisor 抽象类

// 实现父类 matches方法
public boolean matches(Method method, Class clazz) {
//只匹配add方法
return  0 == "add".indexOf(method.getName());
}

//    //切点类匹配规则为 CalcServiceImpl的类或子类,
//    @Override
//    public ClassFilter getClassFilter(){
//        return new ClassFilter(){
//            public boolean matches(Class clazz){
//                return CalcServiceImpl.class.isAssignableFrom(clazz);
//            }
//        };
//    }

public static void main (String [] args){
CalcService target = new CalcServiceImpl();
CalcBeforeAdvice advice = new CalcBeforeAdvice();

// 1 spring 提供的代理工厂
ProxyFactory pf = new ProxyFactory();

// 2 设置代理目标
pf.setInterfaces(target.getClass().getInterfaces());// 指定对接口进行代理,将使用JdkDynamicAopProxy
// 下面两行操作,有任意一行,都将使用Cglib2AopProxy
pf.setOptimize(true);// 启用代理优化,将使用Cglib2AopProxy
pf.setProxyTargetClass(true); // true表示对类进行代理,将使用Cglib2AopProxy

pf.setTarget(target);

// 3 为代理目标添加增强
AddAdvisor advisor = new AddAdvisor();
advisor.setAdvice(advice);

pf.addAdvisor(advisor);

// 4 生成代理实例
CalcService proxy  = (CalcService) pf.getProxy();

System.out.println(proxy.getClass().getName());
proxy.add(2, 3);
}

}


AddAdvisor 继承StaticMethodMatcherPointcutAdvisor
通过Spring配置来定义切面

<bean id="calcBeforAdvice" class="test.CalcBeforeAdvice"/>
<bean id="calcTarget" class="test.CalcServiceImpl"/>
<bean id="addAdvisor" class="test.AddAdvisor"
p:advice-ref="calcBeforAdvice"//向切面注入一个前置增强
/>

<bean id="parent" class="org.springframework.aop.framework.ProxyFactoryBean"
  p:interceptorNames="addAdvisor"
  p:proxyTargetClass="true"
/>

<bean id="calc" parent="parent" p:target-ref="calcTarget"/> //CalcServiceImpl的代理


上面的忒麻烦,我们通过静态正则表达式来匹配

<bean id="calcBeforAdvice" class="test.CalcBeforeAdvice"/>
<bean id="calcTarget" class="test.CalcServiceImpl"/>
<bean id="addRegexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:advice-ref="calcBeforAdvice"//向切面注入一个前置增强 >
<property name="patterns">
  <list>
     <value> .add*</value>//匹配模式串
    </list>
  </property>
</bean>
<bean id="calc" class="org.springframework.aop.framework.ProxyFactoryBean"
   p:interceptorNames="addRegexpAdvisor"
p:target-ref="calcTarget"
  p:proxyTargetClass="true"
/>


Spring提供了6种类型的切点,静态方法切点、动态方法切点、注解切点、表达式切点、流程切点,我能力有限,没有研究下去,仅以静态切点 StaticMethodMatcherPointcut 做个例子就算完事,啥时项目用到了啥时再研究吧。

4.使用AspectJ

Spring AOP应用是比较麻烦的,要实现这个那个接口,写这个那个XML描述,你头疼不?

使用@AspectJ的注解可以非常容易的定义一个切面,不需要实现任何的接口
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: