在Spring中使用AOP实现日志功能

时间:2023-01-16 06:11:24

步骤:
1.创建一个动态WEB项目;
2.导入以下十个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

使用注解的方式实现AOP

在Spring中使用AOP实现日志功能
3.开启基于注解的AOP功能
在配置文件applictionContext.xml中加入

<context:component-scan base-package="com.neuedu.aop"/>
<!-- 开启基于注解的AOP功能 -->
<aop:aspectj-autoproxy/>

4.声明一个切面类,并把这个切面类加入到IOC容器中

@Aspect//表示这是一个切面类
@Component//加入IOC容器
public class LogAspect {}

5.在切面类中声明通知方法
[1]前置通知:@Before
[2]返回通知:@AfterReturning
[3]异常通知:@AfterThrowing
[4]后置通知:@After
[5]环绕通知:@Around :环绕通知是前面四个通知的集合体!

        @Aspect//表示这是一个切面类
@Component//将本类对象加入到IOC容器中!
public class LogAspect {
@Before(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
public void showBeginLog(){
System.out.println("AOP日志开始");
}
@After(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
public void showReturnLog(){
System.out.println("AOP方法返回");
}
@AfterThrowing(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
public void showExceptionLog(){
System.out.println("AOP方法异常");
}
@AfterReturning(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
public void showAfterLog(){
System.out.println("AOP方法结束");
}
}

6.被代理的对象也需要加入IOC容器

        @Component//加入IOC容器
public class MathCalculatorImpl {

public int add(int i,int j){
int result = i+j;
return result;
}
public int sub(int i,int j){
int result = i-j;
return result;
}
public int multi(int i,int j){
int result = i*j;
return result;
}
public int divide(int i,int j){
int result = i/j;
return result;
}
}

方法二 统一声明切入点表达式

//统一式切入点
@Pointcut(value="execution(public * com.neuedu.aop.Mycomputer.*(..))")
public void show(){

}
@Before(value="show()")
public void showBeginLog(JoinPoint point){
Object[] args = point.getArgs();
//获取签名
Signature signature = point.getSignature();
String name = signature.getName();
List<Object> aslist=Arrays.asList(args);

System.out.println(aslist);

args.toString();
System.out.println("方法名:"+name);
System.out.println("日志开始");
}
@After(value="show()")
public void showAfterLog(){
System.out.println("日志正常结束");
}
@AfterThrowing(value="show()" ,throwing= "throwable")
public void showException(JoinPoint joinPoint, Throwable throwable){
System.out.println(throwable.getMessage());
System.out.println("日志出现异常");
}
@AfterReturning(value="show()",returning="result")
public void showFinnalyLog(JoinPoint point,Object result){
System.out.println("目标方法的返回值为:"+result);
System.out.println("日志最终结束");
}

方法三 环绕通知实现

@Around(value="execution(public * com.neuedu.aop.Mycomputer.*(..))")
public Object showLog(ProceedingJoinPoint point){
Object[] args = point.getArgs();
List<Object> asList=Arrays.asList(args);
Object result=null;
Signature signature = point.getSignature();
String name = signature.getName();
try{
try{
//前置通知@Before
System.out.println("目标开始:方法名为"+name+"参数名为"+asList);
result=point.proceed(args);
}
finally{
//后置通知@After
System.out.println("目标后置结束");
}
//返回通知@AfterReturning
System.out.println("目标结束"+result);
}catch(Throwable e){
//异常通知@AfterThrowing
System.out.println("有异常:异常为"+e.getMessage());
}
return result;
}

使用xml文件配置的方式实现AOP

<bean id="mycomputer" class="com.neuedu.aop.Mycomputer"/>
<bean id="nozhujieAspect" class="com.neuedu.aop.NozhujieAspect"/>
<bean id="tscAapect" class="com.neuedu.aop.TscAapect"/>
<aop:config >
<aop:pointcut expression="execution(public * com.neuedu.aop.Mycomputer.*(..))" id="mypiontcut"/>
<aop:aspect ref="nozhujieAspect" order="20">
<aop:before method="showBeginLog" pointcut-ref="mypiontcut"/>
<aop:after method="showAfterLog" pointcut-ref="mypiontcut"/>
<aop:after-throwing method="showException" pointcut-ref="mypiontcut" throwing="ex"/>
<aop:after-returning method="showFinnalyLog" pointcut-ref="mypiontcut" returning="result"/>
</aop:aspect>
<aop:aspect ref="tscAapect" order="10">
<aop:around method="showLog" pointcut-ref="mypiontcut"/>
</aop:aspect>
</aop:config>

需要知道的是:事务的管理是和AOP是有很大关系的,即声明式事务的底层是用事务实现的!

相关文章