
正文
基于XML配置的AOP实现日志打印
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
Spring中可以使用注解或XML文件配置的方式实现AOP。
1、导入jar包
- com.springsource.net.sf.cglib -2.2.0.jar
- com.springsource.org.aopalliance-1.0.0 .jar
- com.springsource.org.aspectj.weaver-1.6.8 .RELEASE.jar
- commons-logging-1.1.3. 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
aspectaop相关jar包 ---> 资源目录--->jar包资源--->AOP日志打印相关jar包(切面类)
Spring相关jar包 ---> 资源目录--->jar包资源--->Spring相关jar包
2、新建代理类和切面类
@Component
public class MathCalculator {
public void add(int i, int j) {
int result=i+j;
System.out.println("目标方法add(int)执行了");
}
public void sub(int i, int j) {
int result=i-j;
System.out.println("目标方法sub执行了");
}
public void mult(int i, int j) {
int result=i*j;
System.out.println("目标方法mult执行了");
}
public void div(int i, int j) {
int result=i/j;
System.out.println("目标方法div执行了");
}
}
MathCalculator
切面类1:LogAspectp1:声明4中通知方法,Before、After、AfterThrowing、AfterReturning
public class LogAspectp1{
public void showBeginLog(JoinPoint jPoint){
Object[] args = jPoint.getArgs();//获取方法参数
List<Object> asList = Arrays.asList(args);//转化成List集合
Signature signature = jPoint.getSignature();
String name = signature.getName();//获取方法的名字
System.out.println("LogAspectp1-----AOP日志开始");
System.out.println("目标方法名:"+name+",参数列表:"+asList);
}
public void showAfterLog(){
System.out.println("LogAspectp1-----AOP方法结束");
}
public void showExceptionLog(Exception ex){
System.out.println("LogAspectp1-----AOP方法异常");
System.out.println("异常信息:"+ex.getMessage());
}
public void showReturnLog(Object result){
System.out.println("方法返回值:"+result);
System.out.println("LogAspectp1-----AOP方法最终返回");
}
}
切面类2:LogAspectp2:声明Around通知方法,代替前面的4中通知
public class LogAspectp2{
public Object showLog(ProceedingJoinPoint point){
Object[] args = point.getArgs();
List<Object> asList = Arrays.asList(args);
Signature signature = point.getSignature();
String name = signature.getName();
Object result = null;
try {
try {
//目标方法之前要执行的操作,相当于@before
System.out.println("LogAspect2-----[环绕日志]"+name+"开始了,参数为:"+asList);
//调用目标方法
result = point.proceed(args);
} finally {
//方法最终结束时执行的操作,相当于@after
System.out.println("LogAspect2-----[环绕日志]"+name+"结束了!");
}
//目标方法正常执行之后的操作,相当于@AfterReturning
System.out.println("LogAspect2-----[环绕日志]"+name+"返回了,返回值为:"+result);
} catch (Throwable e) {
//目标方法抛出异常信息之后的操作,相当于@AfterThrowing
System.out.println("LogAspect2-----[环绕日志]"+name+"出异常了,异常对象为:"+e);
throw new RuntimeException(e.getMessage());
}
return result;
}
}
3、在Spring的配置文件applicationContext.xml中进行配置
<!-- 将需要加载到IOC容器中的bean配置好 -->
<bean id="mathCalculator" class="com.bwlu.common.MathCalculator"></bean>
<bean id="logAspectp1" class="com.bwlu.common.LogAspectp1"></bean>
<bean id="logAspectp2" class="com.bwlu.common.LogAspectp2"></bean>
<!-- 配置AOP,需要导入AOP名称空间 -->
<aop:config>
<!-- 声明切入点表达式 -->
<aop:pointcut expression="execution(public * com.bwlu.aop.MathCalculatorImpl.*(..))" id="pointcut"/>
<!-- 配置日志切面类,引用前面的类 ,通过order属性控制优先级-->
<aop:aspect ref="logAspectp1" order="20">
<!-- 通过method属性指定切面类的切面方法,通过pointcut-ref指定切入点表达式 -->
<aop:before method="showBeginLog" pointcut-ref="pointcut"/>
<aop:after method="showAfterLog" pointcut-ref="pointcut"/>
<aop:after-throwing method="showExceptionLog" pointcut-ref="pointcut" throwing="ex"/>
<aop:after-returning method="showReturnLog" pointcut-ref="pointcut" returning="result"/>
</aop:aspect>
<aop:aspect ref="logAspectp2" order="10">
<aop:around method="showLog" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
4、新建Junit测试类进行测试
ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
@Test
public void test() {
//需要进行强转,如果该类实现了一个接口(并且切入点表达式指向这个类),那么获取到的将不是该类的对象,需要强转
//MathCalculatorImpl实现了MathCalculator接口,则
//MathCalculator bean = (MathCalculator)ioc.getBean("mathCalculatorImpl");
MathCalculator bean = (MathCalculator)ioc.getBean("mathCalculator");
bean.add(10, 5);
System.out.println();
bean.add(10.0, 5);
System.out.println();
bean.sub(10, 5);
System.out.println();
bean.mult(10, 5);
System.out.println();
bean.div(10, 0);
}
运行结果:
LogAspectp2-----[环绕日志]add开始了,参数为:[10, 5]
LogAspectp1-----AOP日志开始
目标方法名:add,参数列表:[10, 5]
目标方法add(int)执行了
LogAspectp1-----AOP方法结束
方法返回值:null
LogAspectp1-----AOP方法最终返回
LogAspectp2-----[环绕日志]add结束了!
LogAspectp2-----[环绕日志]add返回了,返回值为:null LogAspectp2-----[环绕日志]add开始了,参数为:[10.0, 5.0]
LogAspectp1-----AOP日志开始
目标方法名:add,参数列表:[10.0, 5.0]
目标方法add(double)执行了
LogAspectp1-----AOP方法结束
方法返回值:15.0
LogAspectp1-----AOP方法最终返回
LogAspectp2-----[环绕日志]add结束了!
LogAspectp2-----[环绕日志]add返回了,返回值为:15.0 LogAspectp2-----[环绕日志]sub开始了,参数为:[10, 5]
LogAspectp1-----AOP日志开始
目标方法名:sub,参数列表:[10, 5]
目标方法sub执行了
LogAspectp1-----AOP方法结束
方法返回值:null
LogAspectp1-----AOP方法最终返回
LogAspectp2-----[环绕日志]sub结束了!
LogAspectp2-----[环绕日志]sub返回了,返回值为:null LogAspectp2-----[环绕日志]mult开始了,参数为:[10, 5]
LogAspectp1-----AOP日志开始
目标方法名:mult,参数列表:[10, 5]
目标方法mult执行了
LogAspectp1-----AOP方法结束
方法返回值:null
LogAspectp1-----AOP方法最终返回
LogAspectp2-----[环绕日志]mult结束了!
LogAspectp2-----[环绕日志]mult返回了,返回值为:null LogAspectp2-----[环绕日志]div开始了,参数为:[10, 0]
LogAspectp1-----AOP日志开始
目标方法名:div,参数列表:[10, 0]
LogAspectp1-----AOP方法结束
LogAspectp1-----AOP方法异常
异常信息:/ by zero
LogAspectp2-----[环绕日志]div结束了!
LogAspectp2-----[环绕日志]div出异常了,异常对象为:java.lang.ArithmeticException: / by zero
运行结果








