spring-AOP(基于注解方式实现)

预备知识:

Aspectj切入点语法定义

在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut”切入点”

切入点表达式 execution(* com.cwh.spring.aop.impl..(..))"

execution()是最常用的切点函数,其语法如下所示:

整个表达式可以分为五个部分:

1、execution(): 表达式主体。

2、第一个*号:表示返回类型, *号表示所有的类型。

3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.cwh.spring.aop.impl包、子孙包下所有类的方法。

4、第二个*号:表示类名,*号表示所有的类。

5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数

另外的:匹配com.cwh.spring.aop.implo包下所有类的所有方法; execution(* com.cwh.spring.aop.impl..*(..));

下面具体应用的例子: execution(* com.cwh.spring.aop.impl.ArithmeticCalculator.*(int, int))"表示ArithmeticCalculator类下的所有入参为(int, int)的方法

AOP正文:

jar包:

切面类:

package com.cwh.spring.aop.impl;

import java.util.Arrays;
import java.util.List;

import javax.naming.spi.DirStateFactory.Result;

import org.aspectj.lang.JoinPoint;
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.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 *order注解,指定切面的优先级。值越小,优先级越高
 */
@Order(1)
[@Aspect](https://my.oschina.net/aspect)
[@Component](https://my.oschina.net/u/3907912)
public class LoginAspect {

//	/**
//	 * 声明切入点表达式
//	 * @Pointcut(aspectj表达式)注解 
//	 * 别的方法的注解的value引用pointcut注解的方法的方法名即可(此处例子为@After注解的value)
//	 */
//	@Pointcut("execution(public int com.cwh.spring.aop.impl.ArithmeticCalculator.*(int, int))")
//	public void declareJoinpointExprisseion(){}
	
//	//execution执行
//	//Aspect表达式:修饰符、返回类型、类、方法都能使用占位符"*"
//	//public int com.cwh.spring.aop.impl.ArithmeticCalculator.*(int, int)
//	@Before("execution(public int com.cwh.spring.aop.impl.ArithmeticCalculator.*(int, int))")
//	public void beforMethod(JoinPoint joinPoint){
//		//切入点的方法名
//		String methodName = joinPoint.getSignature().getName();
//		//切入点方法入参
//		List<Object> list = Arrays.asList(joinPoint.getArgs());
//		System.out.println("the method:"+methodName+" begin with:"+list);
//	}
//	
//	//后置通知:不能返回目标方法结果。无论是否发生异常,都会执行的。
//	@After("declareJoinpointExprisseion()")
//	public void afterMethod(JoinPoint joinPoint){
//		//切入点的方法名
//		String methodName = joinPoint.getSignature().getName();
		//切入点方法入参
		List<Object> list = Arrays.asList(joinPoint.getArgs());
//		System.out.println("the method:"+methodName+" end");
//	}
//	
//	//可以访问到返回值result
//	@AfterReturning(value = "execution(* com.cwh.spring.aop.impl.ArithmeticCalculator.*(..))",
//					returning="result")
//	public void afterReturnMethod(JoinPoint joinPoint, Object result){
//		System.out.println("r方法:" + joinPoint.getSignature().getName() + " 结果:" + result);
//	}
//	
//	//抛异常后执行的,可以访问到异常对象
//	@AfterThrowing(value = "execution(* com.cwh.spring.aop.impl.ArithmeticCalculator.*(int, int))",
//					throwing="exception")
//	public void afterThrowing(JoinPoint joinPoint, Exception exception){
//		System.out.println("t方法:" + joinPoint.getSignature().getName() + " 发生错误:" + exception);
//	} 
	
	@Around(value="execution(* com.cwh.spring.aop.impl.ArithmeticCalculator.*(int, int))")
	public Object around(ProceedingJoinPoint joinPoint){
		Object result = null;
		String methodName = joinPoint.getSignature().getName();
		
		try {
			//前置通知
			System.out.println("方法前置通知:" + methodName + "参数:" + Arrays.asList(joinPoint.getArgs()));
			//执行目标方法
			result = joinPoint.proceed();
			//后置通知
			System.out.println("方法返回通知:" + result);
		} catch (Throwable e) {
//			e.printStackTrace();
			//异常通知
			System.out.println("the method "+ methodName +" occurs exception:"+e);
		}
		//后置通知
		System.out.println("the method "+ methodName +" ends");
		return result;
	}
}

实现类:

package com.cwh.spring.aop.impl;

import org.springframework.stereotype.Component;

@Component(value = "arithmeticCalculatorImpl")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

	@Override
	public int add(int i, int j) {
		int result = i + j;
		return result;
	}

	@Override
	public int sub(int i, int j) {
		int result = i - j;
		return result;
	}

	@Override
	public int mul(int i, int j) {
		int result = i * j;
		return result;
	}

	@Override
	public int div(int i, int j) {
		int result = i / j;
		return result;
	}

}

接口:

package com.cwh.spring.aop.impl;

public interface ArithmeticCalculator {

	int add(int i, int j);
	int sub(int i, int j);
	
	int mul(int i, int j);
	int div(int i, int j);
	
}

测试类:

package com.cwh.spring.aop.impl;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		// 容器
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

		// 获取bean实例
		// 如果存在切面类,下面写法错误,bean工厂返回的是动态代理对象(不是实现类对象,是代理类的对象,getBean的入参决定了使用哪个实现类的实现方法)
		// ArithmeticCalculatorImpl ari = (ArithmeticCalculatorImpl)
		// context.getBean("arithmeticCalculatorImpl");
		// 如果入参为classtype,子类不能有多个,否则发现不是唯一,不知道注入哪一个。如果是beanId则无妨
		ArithmeticCalculator ari = (ArithmeticCalculator) context.getBean("arithmeticCalculatorImpl");

		// 使用bean
		int result = ari.add(5, 3);
		// 当代理对象调用add方法时,实际上是代理对象委托bean id="arithmeticCalculatorImpl"对象调用
		System.out.println("结果:" + result);
		int result2 = ari.sub(15, 3);
		// 当代理对象调用add方法时,实际上是代理对象委托bean id="arithmeticCalculatorImpl"对象调用
		System.out.println("结果:" + result2);
	}

}

applicationContext.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"
	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.cwh.spring.aop.impl">
				 
		<!--	 annotation:根据注解进行过滤,assignable:根据类进行过滤
			<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
			<context:exclude-filter type="assignable" expression="com.cwh.spring.bean.annotation.service.ApproveInterface"/>
		 -->
		 
		<!-- 如果使用include,需要去掉默认拦截器 use-default-filters="false" 
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
	</context:component-scan>
	
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

转载于:https://my.oschina.net/u/3780366/blog/1831009

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值