一,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共有两种方式:
- 基于AspectJ的xml配置文件的方式
- 基于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配置文件中进行配置
在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">
配置两个类对象
<!-- book对象 --> <bean id="book" class="cn.itcast.aop.Book"></bean> <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
配置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(* *.*(..))