AspectJ教学

本文是一篇关于AspectJ的初级教学,旨在填补市场上针对小白的AOP教学空白。通过 Maven 配置、切面类定义、@Before、@After、@Around 注解的使用,以及结合 Spring 框架,展示了如何在实际操作中应用 AspectJ。文章末尾讨论了使用切面可能带来的‘幽灵拦截器’问题,强调了良好的代码管理和注释的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

3、Mysql分库分表的方法。

4、JFinal框架的学习。

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

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

       下面正式开始!奋斗

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

<span style="font-family:Microsoft YaHei;font-size:14px;">  <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></span>

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

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

2、下面看配置文件:

<span style="font-family:Microsoft YaHei;font-size:14px;">    <!--启动AspectJ注解模式-->
    <aop:aspectj-autoproxy/>
    <!--spring容器扫描包路径-->
    <context:component-scan base-package="com.test"/></span>

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

3、定义切面类

<span style="font-family:Microsoft YaHei;font-size:14px;">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");
    }

}
</span>

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

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

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

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

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


4、业务类

<span style="font-family:Microsoft YaHei;font-size:14px;">@Service
public class Cat {
    public void run () {
        System.out.println("在跑");
    }
}
</span>


5、测试类

<span style="font-family:Microsoft YaHei;font-size:14px;">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:spring-config.xml" })
public class SpringAOPTest1 {
    @Resource
    Cat cat;
    @Test
    public void run() {
        cat.run();
    }
}</span>

文章开头我说过,引入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,不仅要做好代码管理,还要写好注释,这样才能方便别人来维护这些代码。

在spring AOP中我们同样也可以使用类似AspectJ的注解来实现AOP功能,但是这里要注意一下,使AspectJ的注解时,AOP的实现方式还是Spring AOP。

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值