写点什么

Java 开发经验谈:动手造轮子:实现一个简单的 -AOP- 框架

发布于: 2 小时前

{IReadOnlyList<IInterceptor> ResolveInterceptors(IInvocation invocation);}


### IInvocationEnricher
上面?`IInvocation`?的定义中有一个用于扩展的?`Properties`,这个?`enricher`?主要就是基于?`Properties`?来丰富执行上下文信息的,比如说记录?`TraceId`?等请求链路追踪数据,构建方法执行链路等
复制代码


public interface IEnricher<in TContext>{void Enrich(TContext context);}public interface IInvocationEnricher : IEnricher<IInvocation>{}


### AspectDelegate
`AspectDelegate`?是用来将构建要执行的代理方法的方法体的,首先执行注册的?`InvocationEnricher`,丰富上下文信息,然后根据执行上下文获取要执行的拦截器,构建一个执行委托,生成委托使用了之前分享过的?`PipelineBuilder`?构建中间件模式的拦截器,执行拦截器逻辑
复制代码


// apply enrichersforeach (var enricher in FluentAspects.AspectOptions.Enrichers){try{enricher.Enrich(invocation);}catch (Exception ex){InvokeHelper.OnInvokeException?.Invoke(ex);}}


// get delegatevar builder = PipelineBuilder.CreateAsync(completeFunc);foreach (var interceptor in interceptors){builder.Use(interceptor.Invoke);}return builder.Build();


更多信息可以参考源码:?[https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Aspect/AspectDelegate.cs](https://gitee.com/vip204888/java-p7)
## 使用示例
推荐和依赖注入结合使用,主要分为以微软的注入框架为例,有两种使用方式,一种是手动注册代理服务,一种是自动批量注册代理服务,来看下面的实例就明白了
### 手动注册代理服务
使用方式一,手动注册代理服务:
为了方便使用,提供了一些?`AddProxy`?的扩展方法:
复制代码


IServiceCollection services = new ServiceCollection();services.AddFluentAspects(options =>{// 注册拦截器配置 options.NoInterceptProperty<IFly>(f => f.Name);


    options.InterceptAll()        .With<LogInterceptor>()        ;    options.InterceptMethod<DbContext>(x => x.Name == nameof(DbContext.SaveChanges)                                            || x.Name == nameof(DbContext.SaveChangesAsync))        .With<DbContextSaveInterceptor>()        ;    options.InterceptMethod<IFly>(f => f.Fly())        .With<LogInterceptor>();    options.InterceptType<IFly>()        .With<LogInterceptor>();
// 注册 InvocationEnricher options .WithProperty("TraceId", "121212") ;});
复制代码


// 使用 Castle 生成代理 services.AddFluentAspects(options =>{// 注册拦截器配置 options.NoInterceptProperty<IFly>(f => f.Name);


    options.InterceptAll()        .With<LogInterceptor>()        ;    options.InterceptMethod<DbContext>(x => x.Name == nameof(DbContext.SaveChanges)                                            || x.Name == nameof(DbContext.SaveChangesAsync))        .With<DbContextSaveInterceptor>()        ;    options.InterceptMethod<IFly>(f => f.Fly())        .With<LogInterceptor>();    options.InterceptType<IFly>()        .With<LogInterceptor>();
// 注册 InvocationEnricher options .WithProperty("TraceId", "121212") ;}, builder => builder.UseCastle());
复制代码


services.AddTransientProxy<IFly, MonkeyKing>();services.AddSingletonProxy<IEventBus, EventBus>();services.AddDbContext<TestDbContext>(options =>{options.UseInMemoryDatabase("Test");});services.AddScopedProxy<TestDbContext>();


var serviceProvider = services.BuildServiceProvider();



### 批量自动注册代理服务
使用方式二,批量自动注册代理服务:
复制代码


IServiceCollection services = new ServiceCollection();services.AddTransient<IFly, MonkeyKing>();services.AddSingleton<IEventBus, EventBus>();services.AddDbContext<TestDbContext>(options =>{options.UseInMemoryDatabase("Test");});


var serviceProvider = services.BuildFluentAspectsProvider(options =>{options.InterceptAll().With<TestOutputInterceptor>(output);});


// 使用 Castle 来生成代理 var serviceProvider = services.BuildFluentAspectsProvider(options =>{options.InterceptAll().With<TestOutputInterceptor>(output);}, builder => builder.UseCastle());


// 忽略命名空间为 Microsoft/System 的服务类型 var serviceProvider = services.BuildFluentAspectsProvider(options =>{

最后

以上分享的全部分布式技术专题+面试解析+相关的手写和学习的笔记 pdf,高清完整版戳这里免费领取


还有更多 Java 笔记分享如下:



用户头像

还未添加个人签名 2021.07.29 加入

还未添加个人简介

评论

发布
暂无评论
Java开发经验谈:动手造轮子:实现一个简单的-AOP-框架