• 面向切面编程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下的每一个继承类做了什么。

  • 相关阅读:
    提高关键词排名的28个优化技巧
    Web存储机制—sessionStorage,localStorage使用方法
    19个JavaScript简化编码小技巧
    禁止浏览器滚动条滚动,但滚动条可以显示
    H5项目常见问题及注意事项
    利用cookie实现“只弹出一次窗口”的JS代码
    关于JSON.parse在ie6,ie7下未定义的issue
    你真的会使用XMLHttpRequest吗?
    页面内容不足以铺满屏幕高度时,footer居底显示
    CSS box-shadow 属性
  • 原文地址:https://www.cnblogs.com/aoximin/p/12961318.html
Copyright © 2020-2023  润新知