springAOP

1.springAOP 面向切面编程,记录日志、异常处理,通常会用到springAOP,底层使用动态代理实现。但在spring 中,已经帮我们集成好了,只有导入jar包,配置好配置文件,使用注解即可使用。

  1. 首先自己写一个动态代理类,实现打印日志功能。动态代理实现方式有jdk、cglib。这里使用jdk实现。
    编写一个计算器,先写一个接口类:
public interface Cal{
	int add(int num 1,int num 2);
	int sub(int num1,int num 2);
}

编写一个接口的实现类:

public class CalImpl implements Cal{
	public int add(int num 1,int num 2){
		int result = num1+num2;
		return result;
	}
	public int sub(int num 1,int num 2){
		int result = num1-num2;
		return result;
	}
}

实现在计算之前打印参数,计算之后输出结果功能,第一种方式:直接输出

public class CalImpl implements Cal{
	public int add(int num 1,int num 2){
	    System.out.println("参数列表是:"+num1+", "+num2);
		int result = num1+num2;
		System.out.println("计算结果是:"+result );
		return result;
	}
	public int sub(int num 1,int num 2){
	    System.out.println("参数列表是:"+num1+", "+num2);
		int result = num1-num2;
		System.out.println("计算结果是:"+result );
		return result;
	}
}

这样每个方法都输出日志,而且代码有重复,显得代码结构臃肿,若有100个方法要增加100个,若要修改也要修改100个方法,而且要修改源代码,违反了开闭原则,所以下面自己写一个动态代理类:创建类MyInvocationHandler,实现Invocation Handler接口,成为动态代理类

public class MyInvocationHandler implements InvocationHandler{
	//委托代理对象,即被代理的对象
	Object obj = null;
	
	//返回代理对象(添加打印日志的代理对象),供外部调用的方法
	public Object blind( Object obj){
		this.obj = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
	}
	
	//重写 invoke方法
	@Override
	public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
		System.out.println(method.getName()+"参数是:"+Arrays.toString(args));
		// 使用反射,调用方法,invoke()方法,传入obj当前对象,和method方法对应的参数值,可以调用method方法,
		// result 是方法的返回值。
		Object result = method.invoke(this.obj,args);
		System.out.println("计算结果是:"+result );
	}
	
	
}

Proxy.newProxyInstance 方法参数解释:

  • 对象是JVM通过运行时类来创建的,所以要创建一个运行时类,通过obj.getClass().getClassLoader(),来创建,getClassLoader()是获取当前的类加载器,什么是类加载器?简单点说,就是用来加载java类的,类加载器就是负责把class文件加载进内存中,并创建一个java.lang.Class类的一个实例,也就是class对象。
  • 同时要获取这个类的所有信息,所以传入obj.getClass().getInterfaces()参数。
  • this 当前对象。

外部调用:

public class Test{
	public static void main(String[] args){
		Cal cal = new CalImpl();
		MyInvocationHandler handler = new  MyInvocationHandler ();
		Cal cal1 = (Cal) handler.blind(cal);
		cal1.add(3,5);
		cal1.sub(5,9);
	}
}
  1. 使用springAOP实现,创建动态代理类:
@Aspect
@Component
public class logAspect(){

	//com.southwind.aspect.Callmpl.* 是这个包下的所有方法之前都打印日志
	@Before("execution(public int com.southwind.aspect.Callmpl.*(..))")
	public voud before(JoinPoint joinPoint){
		String name = joinPoint.getSignature().getName();
		// 获取参数列表
		String args = Arrays.toString(joinPoint.getArgs());
		System.out.println(name+"参数列表是:"+args);
	}
	
	@After("execution(public int com.southwind.aspect.Callmpl.*(..))")
	public voud before(JoinPoint joinPoint){
		String name = joinPoint.getSignature().getName();
		// 获取参数列表
		String args = Arrays.toString(joinPoint.getArgs());
		System.out.println(name+"方法结束");
	}
}
  • @Before 之前
  • @After 之后
  • @sferReturn return 之后执行
  • @afterThrowing 抛出异常时,用于异常的处理
  • @Before:表示 before 方法执行的时机。execution(public int com.southwind.aspect.CalImpl.*(…)):表示切入点是 com.southwind.aspect 包下 CalImpl 类中的所有方法。即 CalImpl 所有方法在执行之前会首先执行 LoggerAspect 类中的 before 方法。

after 方法同理,表示 CalImpl 所有方法执行之后会执行 LoggerAspect 类中的 after 方法。

afterReturn 方法表示 CalImpl 所有方法在 return 之后会执行 LoggerAspect 类中的 afterReturn 方法。

afterThrowing 方法表示 CalImpl 所有方法在抛出异常时会执行 LoggerAspect 类中的 afterThrowing 方法。

  • pom.xml依赖导入,springmvc.xml 配置省略。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值