Aware接口的一些看法

关于 spring 中的 xxaware接口,aware 的意思是

意识到,对。。。有兴趣

也就是说实现了 aware 接口意味着对这些内容有兴趣。

比如ApplicationEventPublisherAware意味着对ApplicationEventPublisher有兴趣,BeanNameAware则表明对BeanName有兴趣

在 spring 中存在一个标记接口,就叫Awarespring 中所有的 aware 类的接口都继承了这个接口,而所有的 Aware 接口也如其 doc 所说

The actual method signature is determined by individual subinterfaces but should typically consist of just one void-returning method that accepts a single argument.

提供了一个 setxx 的 void 函数。

也许有些同学还不知道,其实这种方法也属于 DI的一种,名为接口注入。

我们一般情况下最经常使用的是 spring 提供的 set 注入和构造器注入,但是在有些时候需要访问 spring 的bean 时,使用 Aware 接口也许是一个更好的选择,至于为什么。。。

我认为这种接口形式的注入更能说明其特征,这个类是关心这部分内容的,也就是说它应该依赖了这部分内容,毕竟如非必要勿增实体,但最好是在需要说明特征时才使用这种方式,其他依赖的情况其实用 set 和 构造器更方便,并且耦合更加松散。

在我自己的项目中有时候也会不得已进行到这一步,某些接口都需要一个成员,成员需要在构造实现类时进行注入,就会增加一个接口,专门用于访问这个成员,之前不知道取什么名字好,一般都是 xxd 或者 xxed,后来学习了 spring 的 aware 之后就都取了这个名字xxAware,看起来也顺眼多了。

比如我希望所有 handler 和 executor接口在执行时打印日志都能够打印 name,创建一个如下接口

interface Named{
  void setName(String name);
} 

而用下面这个接口看起来就更顺眼一些

interface NameAware{
  void setName(String name);
} 

扩展操作

关于 这个 aware 其实也可以解决下面这个问题

如何在自己 new 出来的对象中访问 spring 管理的 bean

一般脑洞不是特别大的情况下,询问百度同学,会找到一个 BeanGet 的类,其实现了 ApplicationContextAware 接口,并且其set 函数实际上是给一个静态变量赋值。看起来没什么问题,用起来稍微注意一下接口的访问时机就好,但总觉得有点变扭,毕竟成员函数操作类变量。

我之前也是这样子做的,但是后来突然开窍了,可以用下面这种更加自然的方式实现

假设需要手动 new 的类为 A,A需要依赖的bean 的类型为 B,手动new A 类的bean 为 C

  1. 声明一个需要依赖的 bean类型的 aware 接口也就是BAware

  2. 在会自行创建实例的 bean 中,也就是 C,注入需要依赖的 bean,也就是 B

  3. 在实现类中实现 AAware 接口

  4. 使用 instanceof 访问接口

原始

interface T{
  //t 的接口
}
class A implements T{
  B b;
  //获取 b
  b=BeanGet.getBean("b",B.class);
  //
}
class C{
  void createA(){
    new A();
  }
}

自然的方式

interface BAware{
  void setB(B b);
}
class A implements T,AAware{
  B b;
  //获取 b
  //b=BeanGet.getBean("b",B.class);不用
  //
  
}
class C{
  B b;//注入到 C
  void createA(){
    T t=new A();
    if(t instanceof AAware)
      t.setB(b)
  }
}
发布了27 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/l1161558158/article/details/103267004
今日推荐