基于Spring-AOP的APIs进行的切面编程示例

一、背景

在Spring的官方文档里,其中《Spring AOP APIs》一章里讲述了使用Spring-AOP的API进行切面编程的方法。地址如下:

https://docs.spring.io/spring/docs/5.2.6.RELEASE/spring-framework-reference/core.html#aop-api

于是简单写了个DEMO以加深巩固;

二、说明

使用Spring-AOP的API进行切面编程与使用注解(@EnableAspectJAutoProxy+@Aspect+@Pointcut+@Around)的思路类似,大致步骤如下:

(1)定义Pointcut切入点;

(2)定义Advice通知

三、示例

Pointcut切入点的配置:接口EmailService的实现类中带有@MyAnn注解的方法;

Advice通知的配置:使用BeforeAdvice前置通知进行拦截处理;

import java.lang.reflect.Method;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Documented
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD })
@interface MyAnn {
}

interface EmailService {

	public String send(String s);
	
	@MyAnn
	public void test();
}

class MyEmailServiceImpl implements EmailService {

	@Override
	public String send(String s) {
		System.out.println("send message :" + s);
		return "ok";
	}

	@MyAnn
	@Override
	public void test() {
		System.out.println("this test function()" );
	}
}


public class Application {

	public static void main(String[] args) {

		// 构造切面的切入点Pointcut
		Pointcut myPointcut = new StaticMethodMatcherPointcut() {

			//切入点为:EmailService的实现类中,标记有@MyAnn注解的方法
			@Override
			public boolean matches(Method method, Class<?> targetClass) {
				if (targetClass.isAssignableFrom(EmailService.class) || method.isAnnotationPresent(MyAnn.class)) {
					return true;
				}

				return false;
			}
		};

		// 设置前置通知方式处理
		BeforeAdvice myBeforeAdvice = new MethodBeforeAdvice() {

			@Override
			public void before(Method method, Object[] args, Object target) throws Throwable {
				System.out.println("!!!!!!!!before advice :" + method.getName());
			}

		};
		
		PointcutAdvisor myAdvisor = new DefaultPointcutAdvisor(myPointcut, myBeforeAdvice);
		
		ProxyFactory factory = new ProxyFactory(new MyEmailServiceImpl());
		factory.addAdvisor(myAdvisor);
		EmailService service = (EmailService) factory.getProxy();
		service.send("xxxx");
		service.test();
	}

}

运行结果:

send message :xxxx
!!!!!!!!before advice :test
this test function()

从结果中可以看出:

MyEmailServiceImpl的两个方法中,只有test()方法进行了前置处理,与预期一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值