zoukankan      html  css  js  c++  java
  • AspectJ教学

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

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

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

    3、Mysql分库分表的方法。

    4、JFinal框架的学习。

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

           那么今儿我们就先来谈一谈AspectJ的实现吧,类似这种文章在CSDN茫茫多,我为什么写这篇文章呢,由于我发现一提到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>

    整个project我採用了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的简单实现,下下次应该会做原理的分析,只是假设自己感觉吃力,就会考虑转载一篇高手的解读~


  • 相关阅读:
    mysql 官网下载,以及安装配置
    SQL 完美解决用逗号分隔存放在一个字段数据
    centos7 开机自动执行shell脚本
    ansible 通过shell脚本执行MySQL语句
    查找让mysql cpu达到100%的罪魁祸首
    查看mysql数据库容量大小
    docker安装zabbix-proxy
    docker zabbix 环境变量
    zabbix 时区不对-误差5个小时--持续更新
    zabbix钉钉告警
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3916051.html
Copyright © 2011-2022 走看看