一:AspectJ
1.AspectJ:java社区里最完整最流行的AOP框架。
2.在spring2.0以上版本中,可以使用基于AspectJ注解或基于XML配置的AOP。
二:在spring中启用AspectJ注解支持
1.要在spring应用中使用AspectJ注解,必需在classpath下包含AspectJ类
- com.springsource.org.aopalliance-1.0.0.jar
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
- spring-aspects-4.0.0.RELEASE.jar
2.将aop schema添加到<Beans>根元素中
3.要在Spring IOC容器中启用AspectJ注解支持,只要在Bean配置文件中定义一个空的XML元素<aop:aspectj-autoproxy>
4.当spring IOC容器侦测到Bean的配置文件中的<aop:aspectj-autoproxy>元素时,会自动为与AspectJ切面匹配到的Bean创建代理
三:创建一个AspectJ注解
1.在lib目录里导入jar包
- com.springsource.org.aopalliance-1.0.0.jar
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
- commons-logging-1.1.1.jar
- spring-aop-4.0.0.RELEASE.jar
- spring-aspects-4.0.0.RELEASE.jar
- spring-beans-4.0.0.RELEASE.jar
- spring-context-4.0.0.RELEASE.jar
- spring-core-4.0.0.RELEASE.jar
- spring-expression-4.0.0.RELEASE.jar
2. 新建一个spring的xml文件,并导入aop,context,beans命名空间。
3.创建一个 ArtithmeticCalculator接口并实现。
package com.dhx.spring.aop.impl;
public interface ArtithmeticCalculator {
//加法运算
int add(int i,int j);
//减法运算
int sub(int i,int j);
//乘法运算
int mul(int i,int j);
//除法运算
int div(int i,int j);
}
package com.dhx.spring.aop.impl;
import org.springframework.stereotype.Component;
@Component
public class ArtithmeticCalculatorImpl implements ArtithmeticCalculator {
@Override
public int add(int i, int j) {
int result=i+j;
return result;
}
@Override
public int sub(int i, int j) {
int result=i-j;
return result;
}
@Override
public int mul(int i, int j) {
int result=i*j;
return result;
}
@Override
public int div(int i, int j) {
int result=i/j;
return result;
}
}
4.创建一个切面类
package com.dhx.spring.aop.impl;
import java.util.Arrays;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
//把这个类声明为一个切面:需要把该类放到IOC容器中,再声明为一个切面
@Aspect
@Component
public class LoggingAspect {
//声明该方法是一个前置通知:在目标方法开始之前执行,其中*为具体的某个方法名,也可以指全部的方法名
@Before("execution(public int com.dhx.spring.aop.impl.ArtithmeticCalculatorImpl.*(int, int))")
public void beforeMethod(JoinPoint joinPoint) {
//方法名
String methodName=joinPoint.getSignature().getName();
//参数
List<Object> args=Arrays.asList(joinPoint.getArgs());
System.out.println("the method "+methodName+" begins with "+args);
}
}
5.在XML文件中配置
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:context="http://www.springframework.org/schema/context"
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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.dhx.spring.aop.impl"></context:component-scan>
<!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
6.测试
package com.dhx.spring.aop.impl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
//1.创建spring 的IOC容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从IOC容器中获取Bean的实例
ArtithmeticCalculator artithmeticCalculator=ctx.getBean(ArtithmeticCalculator.class);
//3.使用Bean
int result=artithmeticCalculator.add(3, 6);
System.out.println("result: "+result);
result=artithmeticCalculator.div(12, 6);
System.out.println("result: "+result);
}
}
四:用AspectJ注解声明切面
1.要在spring中声明AspectJ切面,只需在IOC容器中将切面声明为Bean实例,当在spring IOC容器中初始化AspectJ切面之后,Spring IOC容器就会为那些与AspectJ切面相匹配的Bean创建代理。
2.在AspectJ注解中,切面只是一个带有@Aspect注解的Java类。
3.通知是标注有某种注解的简单java方法。
4.AspectJ支持5中类型的通知注解
- @Before:前置通知,在方法执行之前执行
- @After:后置通知,在方法执行之后执行
- @AfterReturning:返回通知,在方法返回结果之后执行
- @AfterThrowing:异常通知,在方法抛出异常之后
- Around:环绕通知,围绕着方法执行