面向切面编程AOP[三](java AnnotationAwareAspectJAutoProxyCreator实现了什么功能)

前言

要查看一个类实现了什么功能,那么查看它继承的接口或者class即可知道,那么其到底继承了什么?

正文

AnnotationAwareAspectJAutoProxyCreator
extends AspectJAwareAdvisorAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

在这里和ioc相关的有两个东西一个是:

SmartInstantiationAwareBeanPostProcessor,BeanFactoryAware

SmartInstantiationAwareBeanPostProcessor 表示bean 在注入容器前后做些什么。

BeanFactoryAware 是生成工厂。

这个抛开不解释,那么aop需要什么呢?是怎么才能实现aop呢?这里我们需要手写一个aop,这样方便我们理解源码。

下面代码是c#,见谅了,杂学派的。

下面是大内老A写的东西,在此说明。

static void Main(string[] args)
{
	var container = GetContainer();
	container.RegisterType<IFoo, Foo>();
	container.RegisterType<IBar, Bar>();
	var foo = container.Resolve<IFoo>();
	foo.DoSomething();
}

static IUnityContainer GetContainer()
{
	IUnityContainer container = new UnityContainer();
	UnityContainerConfigurator configurator = new UnityContainerConfigurator(container);
	EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());
	container.AddNewExtension<InterceptionExtension>();
	return container;
}

这里一看呢,就是一个ioc功能,因为现在关注的是aop,所以下面只解释aop的功能。

那么什么时候去开启了aop的功能呢?

container.AddNewExtension(); 开启了。

看下InterceptionExtension 到底干了啥子。

public class InterceptionExtension: UnityContainerExtension
{
	protected override void Initialize()
	{
		Context.Strategies.AddNew<InterceptionStrategy>(UnityBuildStage.PreCreation);
	}
}

在初始化的时候会去执行添加一个InterceptionStrategy

那么看下这个InterceptionStrategy是什么?

public class InterceptionStrategy : BuilderStrategy
{
	public IUnityContainer UnityContainer { get; private set; }
	public InjectionMember InterceptionMember { get; private set; }

	public InterceptionStrategy()
	{
		IUnityContainer container = new UnityContainer();
		UnityContainerConfigurator configurator = new UnityContainerConfigurator(container);
		EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());
		this.UnityContainer = container;
		this.InterceptionMember = new InstanceInterceptionPolicySettingInjectionMember(new TransparentProxyInterceptor());
	}

	public override void PostBuildUp(IBuilderContext context)
	{
		if (null == context.Existing ||
			context.Existing.GetType().FullName.StartsWith("Microsoft.Practices") ||
			context.Existing is IInterceptingProxy)
		{
			return;
		}

		context.Existing = this.UnityContainer.Configure<TransientPolicyBuildUpExtension>().BuildUp
			(context.OriginalBuildKey.Type, context.Existing, null, this.InterceptionMember);
	}
}

可以看出这就是一个拦截器。

每次创建一个服务实例的时候就会创建一个执行PostBuildUp 方法。

那么拦截器创建成功的话,那么看下属性类怎么写的。

public class FooCallHandler : ICallHandler
{
	public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
	{
		Console.WriteLine("Foo: Preoperation is executed.");
		var methodReturn = getNext()(input, getNext);
		Console.WriteLine("Foo: Postoperation is executed.");
		return methodReturn;
	}
	public int Order { get; set; }
}

public class FooCallHandlerAttribute : HandlerAttribute
{
	public override ICallHandler CreateHandler(IUnityContainer container)
	{
		return new FooCallHandler { Order = this.Order };
	}
}

上面代码说明了当执行方法前,会执行CreateHandler,然后执行Invoke。

这样就实现了在方法前执行某些东西了。

看下Foo类怎么写的。

public interface IFoo
{
	void DoSomething();
}

[FooCallHandler]
public class Foo : IFoo
{
	public IBar Bar { get; private set; }
	public Foo(IBar bar)
	{ this.Bar = bar; }
	public void DoSomething()
	{
		this.Bar.DoSomething();
	}
}

Foo 只要拥有FooCallHandler特性即可,在java中这个也叫做注解。

那么万变不离其宗。

AnnotationAwareAspectJAutoProxyCreator 里面一定会做一些这样的事情,给容器注册拦截器,然后将拦截事件分发到拦截类。

上面的例子中只是实现了注明了Foo为具体业务逻辑类,并且实现了自己切面类FooCallHandler。

在面向切面编程AOP[一]中,其实只是把这个自己切面类变成一个可以通过注解来配置的切面类而已。

上述这也是解释了为什么aop会放在ioc中,因为aop需要监听那些类实例化了,好为他们注册拦截器,而ioc又是服务的管理实现。

总结

后面详解AnnotationAwareAspectJAutoProxyCreator下的每一个继承类做了什么。

posted @ 2020-05-26 18:39  敖毛毛  阅读(373)  评论(0编辑  收藏  举报