2-6 Spring基于AspectJ的AOP开发:XML的方式

一,AspectJ的概述:

    1,AspectJ是一个面向切面的框架,它扩展了Java语言

    2,AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。

    3,AspectJ是一个基于Java语言的AOP框架。

    4,Spring2.0以后新增了对AspectJ切点表达式的支持

    5,@AspectJ是AspectJ1.5新增的功能,通过JDK5注解技术,允许直接在Bean类中定义切面。

    6,新版本Spring框架,建议使用AspectJ方式来开发AOP,使用AspectJ需要导入Spring AOP和AspectJ相关的Jar包。 

    7,AspectJ并不是Spring框架的一部分,而是一个单独的面向切面的框架,只不过它经常和Spring框架一起使用进行AOP的操作而已。


二,使用AspectJ方式来开发AOP共有两种方式:

  1. 基于AspectJ的xml配置文件的方式
  2. 基于AspectJ的注解的方式


三,Spring使用AspectJ进行AOP的开发:XML的方式

第一步,引入相应的Jar包 
上面我说过,除了导入最基本的Jar包外,使用AspectJ还需要导入Spring AOP和AspectJ相关的Jar包。

  • Spring的传统AOP的开发的包: 
    • spring-aop-4.2.4.RELEASE.jar
    • aopalliance-1.0.jar
  • AspectJ的开发包 
    • aspectjweaver-1.8.7.jar
    • spring-aspects-4.2.4.RELEASE.jar

第二步,编写目标类 
在src目录下创建一个cn.itcast.aop包,并在该包下编写一个目标类。

public class Book {

    public void add() {
        System.out.println("book add.................");
    }

}

第三步,创建增强的类以及增强的方法

public class MyBook {

    // 前置通知
    public void before1() {
        System.out.println("before........");
    }

}

我们现在要求在Book类里面的add方法之前执行MyBook类里面的before1的方法。 
第四步,在Spring配置文件中进行配置

  1. 在Spring配置文件中引入aop约束

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop.xsd">

  2. 配置两个类对象

    <!-- book对象 -->
    <bean id="book" class="cn.itcast.aop.Book"></bean>
    <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>

  3. 配置AOP操作,即需要配置切入点和切面。

    <!-- 配置AOP的操作  -->
    <aop:config>
        <!-- 配置切入点,对Book类里面的所有方法都增强 -->
        <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"></aop:pointcut>
    
        <!-- 配置切面    aop:aspect标签里面使用属性ref,ref属性值写增强类的bean的id值 -->
        <aop:aspect ref="myBook">
            <!-- 
                增强类型
                method属性:增强类的方法名称
                pointcut-ref属性:切入点的id值
            -->
            <!-- 前置通知 -->
            <aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
        </aop:aspect>
    </aop:config>

第五步,编写一个单元测试类并进行测试 
在cn.itcast.aop包下编写一个TestDemo单元测试类。

public class TestDemo {

    @Test
    public void testUser() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book = (Book) context.getBean("book");
        book.add();
    }
}

其实我们也可以整合Junit单元测试,Spring对Junit4进行了支持,可以通过注解方便的测试Spring程序,所以就不必写那么麻烦的单元测试类了。首先导入如下Jar包: 
这里写图片描述 
然后编写如下的单元测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/bean2.xml") // 或者也可写为:@ContextConfiguration("classpath:bean2.xml")
public class TestDemo {

    @Autowired
    private Book book;

    @Test
    public void demo1() {
        book.add();
    }

}

演示其他通知类型

先将MyBook增强类的代码修改为:

public class MyBook {

    // 前置通知
    public void before1() {
        System.out.println("before........");
    }

    // 后置通知
    public void after11() {
        System.out.println("after...........");
    }

    // 环绕通知
    public void around1(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("方法之前执行...........");
        // 让被增强的方法执行
        joinPoint.proceed();
        System.out.println("方法之后执行...........");
    }

}

然后再在Spring配置文件中进行配置。

<!-- 配置AOP的操作  -->
<aop:config>
    <!-- 配置切入点,对Book类里面的所有方法都增强 -->
    <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"></aop:pointcut>

    <!-- 配置切面    aop:aspect标签里面使用属性ref,ref属性值写增强类的bean的id值 -->
    <aop:aspect ref="myBook">
        <!-- 
            增强类型
            method属性:增强类的方法名称
            pointcut-ref属性:切入点的id值
        -->
        <!-- 前置通知 -->
        <aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
        <!-- 后置通知 -->
        <aop:after-returning method="after11" pointcut-ref="pointcut1"></aop:after-returning>
        <!-- 环绕通知 -->
        <aop:around method="around1" pointcut-ref="pointcut1"></aop:around>
    </aop:aspect>
</aop:config>

切入点表达式

通过execution函数,可以定义切点的方法切入。 
语法为:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)。 
例如:

  • 匹配所有类的public方法:execution(public *.*(..))
  • 匹配指定包下所有类的方法:execution(* cn.itcast.dao.*(..)),但不包含子包
  • execution(* cn.itcast.dao..*(..))..*表示包、子孙包下所有类。
  • 匹配指定类所有方法:execution(* cn.itcast.service.UserService.*(..))
  • 匹配实现特定接口的所有类的方法:execution(* cn.itcast.dao.GenericDAO+.*(..))
  • 匹配所有save开头的方法:execution(* save*(..))
  • 匹配所有类里面的所有的方法:execution(* *.*(..))

阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页