-
Notifications
You must be signed in to change notification settings - Fork 52
7. BeanPostProcessor
yuzd edited this page Jul 18, 2021
·
2 revisions
参考Spring框架, 在类的初始化过程中进行自定义逻辑而设计的BeanPostProcessor,有2个方法:
- PostProcessBeforeInitialization
- PostProcessAfterInitialization
该方法在bean实例化完毕(且已经注入完毕),属性设置或自定义init方法执行之前执行!
该方法在bean实例化完毕(且已经注入完毕),在属性设置或自定义init方法执行之后
/// <summary>
/// 測試自己實現一個自定義註解
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public sealed class Soa : Attribute
{
/// <summary>
/// 构造函数
/// </summary>
public Soa(Type type)
{
Type = type;
}
/// <summary>
/// 注册的类型
/// </summary>
internal Type Type { get; set; }
}
这个注解的名字叫Soa,然后有一个构造方法,传参为一个Class Type
下面需要实现一个BeanPostProcessor
[Component]
public class SoaProcessor : BeanPostProcessor
{
//在实例化后且属性设值之前执行
public object PostProcessBeforeInitialization(object bean)
{
Type type = bean.GetType();
////找到bean下所有的字段
var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
foreach (var field in fieldInfos)
{
//看字段上面有没有打Soa自定义注解
var soaAnnotation = field.GetCustomAttribute(typeof(Soa)) as Soa;
if (soaAnnotation == null)
{
continue;
}
//有的话根据注解的参数Type来实例化对象并设值
var instance = Activator.CreateInstance(soaAnnotation.Type) as ISoa;
if (instance == null)
{
continue;
}
field.SetValue(bean, instance);
}
return bean;
}
//不管返回
public object PostProcessAfterInitialization(object bean)
{
return bean;
}
}
好了,实现一个BeanPostProcessor就是写一个类继承并实现它的接口即可。 然后打上[Compoment]注册到容器中即可。
下面测试效果
[Component]
public class Test11Models1
{
[Soa(typeof(SoaTest1))]
private ISoa Soa1;
[Soa(typeof(SoaTest2))]
private ISoa Soa2;
public string getSoa1()
{
return Soa1.say();
}
public string getSoa2()
{
return Soa2.say();
}
}
public interface ISoa
{
string say();
}
public class SoaTest1 : ISoa
{
public string say()
{
return nameof(SoaTest1);
}
}
public class SoaTest2 : ISoa
{
public string say()
{
return nameof(SoaTest2);
}
}
单元测试一下
[Fact]
public void Test1()
{
var builder = new ContainerBuilder();
builder.RegisterSpring(r => r.RegisterAssembly(typeof(TestBeanPostProcessor).Assembly));
var container = builder.Build();
var isRegisterd = container.TryResolve(out Test11Models1 model1);
Assert.True(isRegisterd);
Assert.Equal("SoaTest1",model1.getSoa1());
Assert.Equal("SoaTest2",model1.getSoa2());
}
Test11Models1这个类打了[Compoment]注册到容器,当从容器获取它的时候会走到上面的SoaProcessor。然后识别到里面有打了自定义注解[Soa],并根据注册的参数实例化。