还是前面的案例:
1.需要的jar包.
业务层接口
cn.pro.service.ICustormerService
package cn.pro.service;
//模拟一个业务层的客户接口
public interface ICustormerService {
//保存客户
void saveCustormer();
//更新客户
void updateCustormer(int i);
//删除客户
int deleteCustormer();
}
业务层实现类
cn.pro.service.impl.ICustormerServiceImpl
package cn.pro.service.impl;
import org.springframework.stereotype.Service;
import cn.pro.service.ICustormerService;
//模拟客户业务层的实现类
@Service("iCustormerServiceImpl")
public class ICustormerServiceImpl implements ICustormerService {
public void saveCustormer() {
// TODO Auto-generated method stub
System.out.println("保存了客户");
}
public void updateCustormer(int i) {
// TODO Auto-generated method stub
System.out.println("更新了客户" + i);
}
public int deleteCustormer() {
// TODO Auto-generated method stub
System.out.println("删除了客户");
return 0;
}
}
bean.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" //aop的命名空间
xmlns:context="http://www.springframework.org/schema/context" //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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
//添加扫描的包
<context:component-scan base-package="cn.*"></context:component-scan>
<!-- 开启spring对注解aop的支持 -->
<aop:aspectj-autoproxy/>
</beans>
增强类的配置
1.定义切片(并且定义spring需要扫描的类)
2.在方法上面定义通知类型
.3.定义切入点
cn.pro.utils.Logger
package cn.pro.utils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//一个用来记录日志的类
@Component("logger")
@Aspect
public class Logger {
@Pointcut("execution(* cn.pro.service.impl.*.*(..))")
private void pt1(){}
//记录日志的操作
//前置通知
//@Before("pt1()")
public void printLog(){
System.out.println("loggger中的printLog开始记录日志了。。。。。。");
}
//后置通知
//@AfterReturning("pt1()")
public void printLogAfter(){
System.out.println("loggger中的printLog记录日志结束了。");
}
//异常通知
//@AfterThrowing("pt1()")
public void exceptionAfter(){
System.out.println("异常异常........。");
}
//最终通知
//@After("pt1()")
public void finalAfter(){
System.out.println("最终最终........。");
}
//配置环绕通知
/*
* 环绕通知:
* 它是spring框架为我们提供的一种可以在代码中手动控制通知方法什么时候执行的方式
* 问题:
当配置了环绕通知后,切入点里面方法没有执行,而环绕通知里面的代码执行了
分析:由动态代理可知:环绕通知指的是invoke方法并且里面有明确的接入点方法调用,而我们现在方法没有明确的切入点调用
解决:
spring为我们提供了一个接口:proceedingjoinpoint,该接口可以作为环绕通知的方法参数来使用
*在程序运行时,spring框架,会为我们提供该接口的实现类,供我们使用。
*该接口中有一个方法,proceed(),它的作用就相当于method.invoke()方法,就是明确调用业务层核心方法,就是切入点方法。
*/
@Around("pt1()")
public Object roundadvice(ProceedingJoinPoint pjp){
Object RtValue = null;
try {
//可以写前置通知
System.out.println("环绕通知开始");
System.out.println("记录日志前");
RtValue = pjp.proceed();
//后置通知
System.out.println("记录日志后");
} catch (Throwable e) {
// TODO Auto-generated catch block
//异常通知
System.out.println("异常异常");
e.printStackTrace();
}finally{
//最终通知
System.out.println("最终要做的事情");
System.out.println("环绕通知结束");
}
return RtValue;
}
}
测试类:
执行结果
纯注解aop配置
上述配置还是需要xml配置文件的,如果完全不使用xml文件该怎么配置呢?
新建一个类
config.SpringConfuguration
package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration //声明配置类
@ComponentScan("cn.pro") //扫描的包
@EnableAspectJAutoProxy //开启aop注解
public class SpringConfuguration {
}
测试类:
测试结果跟上面一样。
aop传入参数
@Pointcut(value ="execution(* com.loveread.controller.ConfigController.getGameConfig(..)) && args(type,name,unit,gameNum)",argNames = "type,name,unit,gameNum")
public void setParamPointcut(String type,String name,String unit,String gameNum){}
@Around(value = "setParamPointcut(type,name,unit,gameNum)", argNames = "type,name,unit,gameNum")
public Object dealParam(ProceedingJoinPoint joinpoint,String type,String name, String unit,String gameNum) throws Throwable{