前置通知 :在连接点前执行,不会影响连接点的执行 除非抛异常
异常通知 :在连接点抛出异常后执行
环绕通知 :围绕在一个通知点前后,是最强大的通知类型
- 创建service包及service类
package com.sunqg.service.imp;
import org.springframework.stereotype.Service;
import com.sunqg.service.ProductService;
public class ProductServiceImp implements ProductService {
@Override
public void browseBefore(String loginName, String ProductName) {
// TODO Auto-generated method stub
System.out.print("执行业务方法 前置通知");
}
@Override
public void browseThrow(String loginName, String productName) {
// TODO Auto-generated method stub
System.out.print("模拟用户浏览 异常通知");
throw new RuntimeException("特定的异常通知");
}
@Override
public void browseAround(String loginName, String productName) {
// TODO Auto-generated method stub
System.out.print("模拟用户浏览 环绕通知");
//延长方法的执行时间编便于展示环绕通知的效果
int i = 100000;
while(i>0)
i--;
}
@Override
public void browseAfter(String loginName, String productName) {
// TODO Auto-generated method stub
System.out.print("模拟用户浏览 返回通知");
}
}
- 创建aop包,日志通知类及日志记录方法
package com.sunqg.aop;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
public class AllLogAdvice {
//使用此方法作为前置通知-日志
public void BeforeAdvice(JoinPoint joinPoint){
//获取业务方法的参数 通过getArgs方法可获得业务方法的参数
List<Object> args = Arrays.asList(joinPoint.getArgs());
//定义日志格式
String logInfoText = "\n前置通知:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())
+args.get(1).toString() + "浏览商品" + args.get(1).toString();
//输出日志
System.out.print(logInfoText);
}
public void AfterAdvice(JoinPoint joinPoint){
//获取方法参数
List <Object> args = Arrays.asList(joinPoint.getArgs());
String logInfoText = "\n返回通知:" + new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date())
+ args.get(1).toString();
System.out.print(logInfoText);
}
public void ThrowAdvice(JoinPoint joinPoint,Exception e){
//获取被调用的类名
String targetClassName = joinPoint.getTarget().getClass().getName();
//获取被调用的方法名
String targetMethodName = joinPoint.getSignature().getName();
//定义日志格式的字符串
String logInfoText = "\n异常通知:执行" + targetClassName + "类的" + targetMethodName + "方法时出现异常";
//将日志信息输出
System.out.println(logInfoText);
}
public void AroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable{
long beginTime = System.currentTimeMillis();
joinPoint.proceed();
long endTime = System.currentTimeMillis();
//获取被调用的方法名
String targetMethodName = joinPoint.getSignature().getName();
//日志格式字符串
String logInfoText = "\n环绕通知:" + targetMethodName + "方法调用前的时间为" + beginTime + "毫秒," + "调用后的时间为:"
+ endTime + "毫秒";
System.out.print(logInfoText);
}
}
- 编写配置文件
<?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/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.sunqg"></context:component-scan>
<!-- 实例化处理 -->
<bean id="productService" class="com.sunqg.service.imp.ProductServiceImp"></bean>
<bean id="allLogAdvice" class="com.sunqg.aop.AllLogAdvice"></bean>
<!-- 配置aop -->
<aop:config>
<!-- 配置日志切面 -->
<aop:aspect id="logaop" ref="allLogAdvice">
<!-- 定义切入点:对browse方法进行拦截 -->
<aop:pointcut expression="execution(public void browseBefore(String,String))" id="logpointcut"/> <!-- 此处只对此方法进行演示 -->
<!-- 将日志通知类中的BeforeAdvice方法指定为前置通知 -->
<aop:before method="BeforeAdvice" pointcut-ref="logpointcut"/>
<!-- 将日志通知类中的AfterAdvice方法指定为后置通知 -->
<aop:after method="AfterAdvice" pointcut-ref="logpointcut"/>
<!-- 将日志通知类中的ThrowAdvice方法指定为异常通知 -->
<aop:after-throwing method="ThrowAdvice" pointcut-ref="logpointcut" throwing = "e"/>
<!-- 将日志通知类中的AroundAdivice方法指定为环绕通知 -->
<aop:around method="AroundAdvice" pointcut-ref="logpointcut"/>
</aop:aspect>
</aop:config>
</beans>
package com.sunqg.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.sunqg.service.ProductService;
import com.sunqg.service.UserService;
public class TestLogin {
@Test
public void main(){
//1.加载applicationContext文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ProductService productService = (ProductService) ctx.getBean("productService");
productService.browseBefore("sunqg", "框架技术精讲与案例整合");
productService.browseAfter("sunqg", "框架技术精讲与案例整合");
productService.browseAround("sunqg", "框架技术精讲与案例整合");
productService.browseThrow("sunqg", "框架技术精讲与案例整合");
}
}