一、基于注解的AspectJ
1、要在spring应用中使用AspectJ注解,必须在classpath下包含AspectJ类库:
com.springsource.org.aopalliance.jar 和 com.springsource.org.aspectj.weaver.jar;将aop schema添加到 <beans> 根元素中;在Spring IoC 容器中启用 AspectJ直接支持,只要在 bean 配置文件中定义一个空的XML元素 <aop:aspectj-autoproxy>;当Spring IoC 容器检测到 bean 配置文件中的 <aop:aspectj-autoproxy> 元素时,就会自动为与 AspectJ 切面匹配的 bean 创建代理。
2、通知是标有某种注解的简单的java方法,AspectJ支持5种类型的通知注解:
1)@Before:前置通知,在方法执行之前执行
2)@After:最终增强
3)@AfterReturning:后置通知,在方法返回结果之后执行
4)@AfterThrowing:异常通知,在方法抛出异常后执行
5)@Around:环绕通知,围绕着方法的执行
3. 典型的切点表达式是根据方法的签名来匹配各种方法:
-execution(* *.*(..)):第一个*代表匹配任意修饰符和返回值,第二个*代表任意类的对象,第三个*代表任意方法,参数列表中..匹配任意数量的参数。
- execution (* com.bupt.springtest.aop.ArithmeticCalculator.*(..)):匹配 ArithmeticCalculator 中声明的所有方法,第一个 * 代表任意修饰符及任意返回值;第二个 * 代表任一方法; .. 匹配任意数量的参数。若目标类或接口与该切面在同一个包中,可以省略包名。
- execution (public double ArithmeticCalculator.*(double, ..)):匹配第一个参数为double类型的方法, .. 匹配任意数量任意类型的参数
- execution (public double ArithmeticCalculator.*(double, double)):匹配参数类型为double, double类型的方法
4、案例
1、创建一个接口
package cn.happy.service;
public interface ISomeService {
public void doSome();
public String add();
public void insert();
public void update();
public void delete();
public void select();
}
2、实现接口类
package cn.happy.service;
public class SomeService implements ISomeService {
public void doSome() {
System.out.println("code ok");
}
public String add() {
System.out.println("=========log日志===============");
//int i = 5/0;
return "add";
}
public void insert() {
System.out.println("insert");
}
public void update() {
System.out.println("update");
}
public void delete() {
System.out.println("delete");
}
public void select() {
int i = 5/0;
System.out.println("select");
}
}
3、编写增强类
package cn.happy.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class MyAspect {
@Before(value="execution(* *..service.*.*(..))")
public void myAspectj(){
System.out.println("---我是前置增强---");
}
@AfterReturning(value="execution(* *..service.*.*(..))")
public void myAspectjAfter(){
System.out.println("---我是后置增强---");
}
@Around(value="execution(* *..service.*.*(..))")
public Object myAspectjAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("---我是环绕前增强---");
Object result = proceedingJoinPoint.proceed();
System.out.println("---我是环绕后增强---");
if (result!= null) {
String str = (String)result; //可以改变返回值
return str.toUpperCase();
} else {
return null;
}
}
异常增强
@Pointcut("execution(* *..service.*.*(..))") 表达式注解
public void myPoincut(){}
@AfterThrowing("myPoincut()")
public void throwing(){
System.out.println("---error---");
}
//切点表达式
@Pointcut("execution(* *..service.*.insert(..))")
public void insert(){}
@Pointcut("execution(* *..service.*.update(..))")
public void update(){}
@Pointcut("execution(* *..service.*.delete(..))")
public void delete(){}
@Before("insert()||update()||delete()")
public void myAspectj(){
System.out.println("---我是前置增强开启事物---");
}
//最终增强
@After("execution(* *..service.*.*(..))")
public void after(){
System.out.println("我是最终增强");
}
}
4、编写xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
">
<!--注解实现-->
<!--目标对象-->
<bean id="SomeService" class="cn.happy.serviceXML.SomeService"></bean>
<!--增强 通知–> -->
<bean id="beforeAdvice" class="cn.happy.service.MyAspect"></bean>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
5、编写测试类
package cn.happy;
import cn.happy.service.ISomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
@Test
public void testAspect(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ISomeService someService = (ISomeService)context.getBean("SomeService");
someService.insert();
someService.update();
someService.delete();
someService.select();
}
}
二、基于xml的AspectJ实现
1、基于xml的实现需要在xml配置文件中加入<aop>节点。
2、案例
1)创建接口类
package cn.happy.serviceXML;
public interface ISomeService {
public void doSome();
public String add();
}
2)实现接口类
package cn.happy.serviceXML;
public class SomeService implements ISomeService {
public void doSome() {
System.out.println("code ok");
}
public String add() {
System.out.println("log------");
//int i = 5/0;
return "add";
}
}
3)编写增强类
package cn.happy.serviceXML;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect {
public void myBefore(){
System.out.println("=========before============");
}
public void after(){
System.out.println("============after===============");
}
public Object myArround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("我是环绕前增强");
Object result = proceedingJoinPoint.proceed();
System.out.println("我是环绕后增强");
if (result!= null) {
String str = (String)result; //可以改变返回值
return str.toUpperCase();
} else {
return null;
}
}
}
4).编写xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
">
<!--目标对象-->
<bean id="SomeService" class="cn.happy.serviceXML.SomeService"></bean>
<!--增强类-->
<bean id="aspect" class="cn.happy.serviceXML.MyAspect"></bean>
<!--aop-->
<aop:config>
<!--设置一个切点-->
<aop:pointcut id="mycut" expression="execution(* *..serviceXML.*.*(..))"></aop:pointcut>
<aop:aspect ref="aspect">
<aop:before method="myBefore" pointcut-ref="mycut"></aop:before>
<!--<aop:after-returning method="after" pointcut-ref="mycut"></aop:after-returning>-->
<!--<aop:around method="myArround" pointcut-ref="mycut"></aop:around>-->
</aop:aspect>
</aop:config>
</beans>
5)编写测试类
package cn.happy;
import cn.happy.serviceXML.ISomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test01 {
// AspectJ XML
@Test
public void testAspectXML(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ISomeService someService= (ISomeService)context.getBean("SomeService");
someService.add();
someService.doSome();
}
}