Home  >  Article  >  Database  >  AOP框架之AspectJ简介

AOP框架之AspectJ简介

WBOY
WBOYOriginal
2016-06-07 15:58:321386browse

这几天看JAVA基础看的有点头疼,决定时不时的换换口味,准备开始调研一些现在流行的技术,于是,开始埋头思考自己知识的盲区(当时,自己的知识盲区茫茫多...),想了几天后,决定要开始研究一下几种技术及实现原理。 1、AOP技术应用及实现原理。 2、quartz

这几天看JAVA基础看的有点头疼,决定时不时的换换口味,准备开始调研一些现在流行的技术,于是,开始埋头思考自己知识的盲区(当时,自己的知识盲区茫茫多...),想了几天后,决定要开始研究一下几种技术及实现原理。

1、AOP技术应用及实现原理。

2、quartz调度的DB持久模式及集群模式的实现及原理。

3、Mysql分库分表的方法。

4、JFinal框架的学习。

目前先暂定这个日常把,毕竟想搞定一块以我的水平来看,都得一周时间。

那么今儿我们就先来谈一谈AspectJ的实现吧,类似这样的文章在CSDN茫茫多,我为什么写这篇文章呢,因为我发现一提到AOP都是各路神仙开始讲SpringAOP与AspectJ的区别,要么就是SpringAOP的实现原理,感觉市面上缺少小白级别的文章,恰逢鄙人不才~SpringAOP的源码看着没啥灵感,也就只能写写这种教学文章了。

下面正式开始!奋斗

1、首先是Maven配置,下面是需要引的包:

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
        <version>4.10</version>
      <scope>test</scope>
    </dependency>
      <!--springr容器-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--AspectJ包-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.7.4</version>
    </dependency>
    <!--通过SpringJUnit4ClassRunner注解测试-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>3.1.0.RELEASE</version>
      <scope>test</scope>
    </dependency>

整个工程我采用了spring的框架结构,版本号为3.2.0.RELEASE。

Junit我用了4.1版本,为了方便测试的时候不用再编写一连串的代码来读取spring容器。

2、下面看配置文件:

    <!--启动AspectJ注解模式-->
    <aop:aspectj-autoproxy/>
    <!--spring容器扫描包路径-->
    <context:component-scan base-package="com.test"/>

就两行~注解都解释的很清楚了。

3、定义切面类

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Service;

/**
 * Created with IntelliJ IDEA.
 * User: 菜鸟大明
 * Date: 14-7-11
 * Time: 上午10:03
 * To change this template use File | Settings | File Templates.
 */
@Service
@Aspect
public class AspectBean {

    /** 必须为final String类型的,注解里要使用的变量只能是静态常量类型的 */
    final static String expression = "execution(* com.test.*..*.*(..))";

    // 第一种方式,定义Pointcut标签
    @Pointcut("execution(* com.test.*..*.*(..))")
    private void pointCutMethod() {
    }
    // Before里传入@Pointcut所注解的方法
    @Before("pointCutMethod()")
    public void before() {
        System.out.println("before");
    }

    @After(expression)
    public void after() {
        System.out.println("after");
    }
    // 第二种方式,直接传入执行表达式
    @Around(expression)
    public void around(ProceedingJoinPoint joinPoint) {
        System.out.println("around before");
        try {
            joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("around after");
    }

}

这里我稍微说详细一点,那么@Service我就一句带过了,就是注入容器,否则的话,你需要在spring-config.xml里定义这个bean。

@Aspect就是定义这个类为切面,这块其实挺不好理解的,如果理解不上去,就把@Aspect的注解类,当成是AOP横切的母体。

@Before就是在这个类执行前运行。

@After就是在这个类执行后运行。

@Around这个其实跟Struts2里的拦截器功能是一样的,内部的实现也是类似。这种模式更灵活,也是我们平时运用最多的方式。但要记得这可是代理模式,如果想用反射操作业务类的话,你取到的可是代理。

4、业务类

@Service
public class Cat {
    public void run () {
        System.out.println("在跑");
    }
}

5、测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:spring-config.xml" })
public class SpringAOPTest1 {
    @Resource
    Cat cat;
    @Test
    public void run() {
        cat.run();
    }
}

文章开头我说过,引入Junit 4.1以上的版本的目的就是为了省略那一长串读取容器的写法。

省略了ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");

6、输出结果:

around before
before
在跑
around after
after

我们不用关心是Around 和 Before After的执行顺序,因为在正常的情况下,Around 与 Before、After很少在一起使用的。

总结:AspectJ给我的感觉比SpringAOP写法更方便,不需要在xml里嵌入过多的代码。但有一个问题,实际项目中,使用这种POJO注解方式可能会给我们带来“幽灵拦截器”。我们仔细观察发现,要实现这个AOP功能,我们不需要嵌入任何业务代码、业务上下文中,在自己的地盘儿写好代码,但这会造成什么问题呢?

如果我们项目的管理目录没有做好,@AspectJ类到处飘,我们很难判断到底有多少拦截器在对“包装”我们的逻辑,要想查找这些拦截器,只能全文搜索“@Aspect”再一个个去检查。因此,想正确的使用AspectJ,不仅要做好代码管理,还要写好注释,这样才能方便别人来维护这些代码。

下次我会带来SpringAOP的简单实现,下下次应该会做原理的分析,不过如果自己感觉吃力,就会考虑转载一篇高手的解读~




Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn