编程方式实现AOP

示例

  1. 定义Advice
public class LogMethodInterceptor implements MethodInterceptor{

	private LogPrinter printer;
	
	public LogMethodInterceptor(LogPrinter printer) {
		this.printer = printer;
	}

	public LogMethodInterceptor() {
		this.printer = new SysLogPrinter();
	}

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		printer.printLog();
		return invocation.proceed();
	}

}
  1. 定义Advicor
public class AbstractLogAdvisorPostProcessor extends ProxyProcessorSupport implements BeanPostProcessor{

	private static final long serialVersionUID = -6245858583504116328L;
	protected Advisor advisor;
	protected boolean beforeExistingAdvisors = false;
	private final Map<Class<?>, Boolean> eligibleBeans = new ConcurrentHashMap<Class<?>, Boolean>(256);

	public void setBeforeExistingAdvisors(boolean beforeExistingAdvisors) {
		this.beforeExistingAdvisors = beforeExistingAdvisors;
	}
	
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof AopInfrastructureBean) {
			// Ignore AOP infrastructure such as scoped proxies.
			return bean;
		}

		if (bean instanceof Advised) {
			Advised advised = (Advised) bean;
			if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
				// Add our local Advisor to the existing proxy's Advisor chain...
				if (this.beforeExistingAdvisors) {
					advised.addAdvisor(0, this.advisor);
				}
				else {
					advised.addAdvisor(this.advisor);
				}
				return bean;
			}
		}

		if (isEligible(bean, beanName)) {
			ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
			if (!proxyFactory.isProxyTargetClass()) {
				evaluateProxyInterfaces(bean.getClass(), proxyFactory);
			}
			proxyFactory.addAdvisor(this.advisor);
			customizeProxyFactory(proxyFactory);
			return proxyFactory.getProxy(getProxyClassLoader());
		}

		// No async proxy needed.
		return bean;
	}
	
	protected boolean isEligible(Class<?> targetClass) {
		Boolean eligible = this.eligibleBeans.get(targetClass);
		if (eligible != null) {
			return eligible;
		}
		eligible = AopUtils.canApply(this.advisor, targetClass);
		this.eligibleBeans.put(targetClass, eligible);
		return eligible;
	}
	
	protected boolean isEligible(Object bean, String beanName) {
		return isEligible(bean.getClass());
	}
	
	protected ProxyFactory prepareProxyFactory(Object bean, String beanName) {
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);
		proxyFactory.setTarget(bean);
		return proxyFactory;
	}

	protected void customizeProxyFactory(ProxyFactory proxyFactory) {
	}
}

public class LogPostProcessor extends AbstractLogAdvisorPostProcessor implements InitializingBean {

	private static final long serialVersionUID = 3188630240751916965L;
	private Class<? extends Annotation> validatedAnnotationType = LoggerAnn.class;
	private LogPrinter printer;
	
	public LogPrinter getPrinter() {
		return printer;
	}

	public void setPrinter(LogPrinter printer) {
		this.printer = printer;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
	    // 创建Pointcut
		Pointcut pointcut = new AnnotationMatchingPointcut(validatedAnnotationType,true);
		// 传入Pointcut和Advice,创建Advisor
		this.advisor = new DefaultPointcutAdvisor(pointcut, createLogAdvice(this.printer));
	}
	
	private LogMethodInterceptor createLogAdvice(LogPrinter printer) {
		return printer == null ? new LogMethodInterceptor() : new LogMethodInterceptor(printer);
	}
}

示例完整代码

重要类图。

ProxyFactory

类图
在这里插入图片描述
ProxyFactory继承了ProxyCreatorSupport类,持有了AopProxyFactory,AdvisorChainFactory,

List。等

作用
AopProxyFactory基于 AdvisedSupport 配置信息,生成AOP 代理对象.默认为“DefaultAopProxyFactory”
AdvisorChainFactoryadvisor链。默认实现为DefaultAdvisorChainFactory,只有一个方法,获取Advised满足条件的MethodInterceptor列表或DynamicInterceptionAdvice列表
Advisor持有AOP advice和pointcut
ProxyConfig生成代理对象的配置元信息

Advice&Pointcut&Advisor

Adivce类图

在这里插入图片描述

Pointcut类图
在这里插入图片描述

Advisor类图
在这里插入图片描述

Advisor是设计的核心元素,起到承上启下的作用,连接着Advice和Pointcut。默认实现是:DefaultPointCutAdvisor。需要知道2个接口ClassFilter,MethodMatcher,通过方法名,就可以判定他们的作用了,主要用在"匹配"上。

ClassFilter,MethodMatcher

代码AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply():
获取可以匹配的增强器

protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}

在AOPUtil类中我们发现

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		if (advisor instanceof IntroductionAdvisor) {
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		else {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		if (!pc.getClassFilter().matches(targetClass)) {// 获取Pointcut中的ClassFilter对象进行匹配
			return false;
		}

		MethodMatcher methodMatcher = pc.getMethodMatcher();// 获取Pointcut中的MethodMatcher对象进行匹配
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(targetClass);
		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值