spring aop

文章目录

aop术语:
  • 通知(advice)
    切面的工作被称为通知,分为以下几种
类型注解
前置通知(before)@Before
后置通知(after)@After
返回通知(after-returning)@AfterReturning
异常通知(after-throwing)@AfterThrowing
环绕通知(around)@Around
  • 连接点(join point)
    符合插入通知规则的点
  • 切点(pointcut)
    定义连接点的范围,常用切点表达式语言(部分举例)
aspectJ指示器描述举例举例描述
arg()限制连接点匹配参数为指定类型的执行方法execution(* springBase.aop.IService.count(int)) && args(count)指定使用IService接口中count方法的方法,并将方法的参数传入同通知
@args限制连接点匹配参数由指定注解标注的执行方法
execution()用于匹配连接点的执行方法execution(* springBase.aop.IService.add(…))指定使用IService接口中add方法的方法
this()限制连接点匹配AOP代理的bean引用为指定类型的类
target限制连接点匹配目标对象为指定类型的类
@target限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解
with限制连接点匹配指定的类型execution(* springBase.aop.IService.add(…)) && within(springBase.aop.demo.*)使用within限定包范围
@with限制连接点匹配指定注解所标注的类型
@annotation限定匹配带有指定注解的连接点@annotation(springBase.aop.Action)指定标有@Action注解的方法
bean限定匹配指定的beanexecution(* springBase.aop.IService.add(…)) && bean(serviceImpl)指定实现IService接口并且名称为serviceImpl的bean
  • 切面(aspect)
    通知和切点的结合,定义在何时何地完成此通知的功能
  • 引入(introduction)
  • 织入(weaving)
    将通知的代码在连接点调用,织入时机可以发生在编译期、类加载期、运行期(spring aop的方式)
举例

配置类:

@Configuration
@ComponentScan("springBase.aop")
@EnableAspectJAutoProxy//启动aspectj自动代理
public class JavaConfig {
}

切面类:

//注解切面:
@Aspect // 声明一个切面
@Component
public class LogAspect {
	@Pointcut("@annotation(springBase.aop.Action)") // 注解声明切点,也可以声明其他的条件的切点
	public void annotationPointCut() {
	};

	//注解切点和获取注解的方法一:通过获取方法对象获取注解对象
	@After("annotationPointCut()")
	public void after(JoinPoint joinPoint) {//这是一个通知
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		Action action = method.getAnnotation(Action.class);
		System.out.println("注解式拦截 " + action.name());
	}	
	//注解切点和获取注解的方法二:通过参数直接获取注解对象(推荐)
	@After("annotationPointCut()&&@annotation(action)")
	public void after(JoinPoint joinPoint,Action action) {
		System.out.println("注解式拦截 " + action.name());
	}
}
//方法过滤:
@Aspect // 声明一个切面
@Component
public class LogAspect {
	// 表示接口springBase.aop.IService名为add的方法(任意返回值和任意参数),使用within限定必须在springBase.aop.demo包下
	@Before("execution(* springBase.aop.IService.add(..)) && bean(serviceImpl)")
	public void before(JoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		Class<?> c = joinPoint.getTarget().getClass();
		System.out.println("方法式拦截, " + c.getName() + "," + method.getName());
	}
}
//环绕:
@Aspect // 声明一个切面
@Component
public class LogAspect {
	// 环绕必须要调用原方法
	@Around("execution(* springBase.aop.IService.add(..)) && bean(serviceImpl)")
	public void around(ProceedingJoinPoint pj) {
		Object[] args = pj.getArgs();// 可以获取方法入参
		System.out.println("方法入参:" + args);
		MethodSignature signature = (MethodSignature) pj.getSignature();
		Method method = signature.getMethod();
		Class<?> c = pj.getTarget().getClass();
		System.out.println("around前, " + c.getName() + "," + method.getName());
		try {
			Object ret = pj.proceed();// 调用原方法,在此处可以获取方法返回值
			System.out.println("返回值:" + ret);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		System.out.println("around后, " + c.getName() + "," + method.getName());
	}
}
//处理参数:
@Aspect // 声明一个切面
@Component
public class LogAspect {
	// 带参数的情况处理,声明一个入参为int并且入参名称为count的切点
	@Pointcut("execution(* springBase.aop.IService.count(int)) && args(count)")
	public void parameters(int count) {
	};

	@Before("parameters(count)")
	public void countBefore(int count) {
		System.out.println("count=" + count);
	}
}
//增强接口:
//注入新功能,此处实现给IService接口增加IOtherService接口的功能,并提供默认实现OtherServiceImpl
@DeclareParents(value = "springBase.aop.IService+", defaultImpl = OtherServiceImpl.class)
public static IOtherService otherService;

客户端:

public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
		DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
		IService demoMethodService = context.getBean("demoMethodService", IService.class);
		IService serviceImpl = context.getBean("serviceImpl", IService.class);
		//注解切面
		demoAnnotationService.add();
		//方法过滤
		demoMethodService.add();
		serviceImpl.add();
		//处理参数
		serviceImpl.count(10);
		//增强接口
		IOtherService otherService = (IOtherService)serviceImpl;IOtherService otherService = (IOtherService)serviceImpl;
		otherService.otherMethod();
		context.close();
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值