Java使用@EnableEurekaServer实现自动装配详解

作者:hongmin.shm 时间:2023-08-23 19:50:32 

实践

仿照@EnableEurekaServer实现自动装配

如果你使用过Eureka作为微服务的注册中心,那么对@EnableWebConfigure一定很了解,该注解用来开启Eureka服务端作为微服务的注册中心,其背后是springboot自动装配原理。

本次,将仿照此设计思路,完成Web应用统一异常处理、TraceId链路日志追踪、Json序列化消息处理器等通用能力的自动装配。

@EnableEurekaServer

通过源码我们得知,此注解的源码如下

/**
* Annotation to activate Eureka Server related configuration.
* {@link EurekaServerAutoConfiguration}
*
* @author Dave Syer
* @author Biju Kunjummen
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EurekaServerMarkerConfiguration.class)
public @interface EnableEurekaServer {
}

那么,如何通过在启动类标识此注解即可实现EurekaServer的自动装配呢?

答案其实在这一句

@Import(EurekaServerMarkerConfiguration.class)

该注解使用了@Import注解导入了一个配置类 EurekaServerMarkerConfiguration.java,该配置类源码如下

@Configuration(proxyBeanMethods = false)
public class EurekaServerMarkerConfiguration {
@Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
}
class Marker {
}
}

我们看到,该配置类声明了一个Bean 内部类Marker

那么,为什么声明这个类?这个类看起来没有任何属性和方法

我们在导入的EurekaServer包中继续寻找答案

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

通过Command + 单击 Marker类,我们看到了如下引用

Java使用@EnableEurekaServer实现自动装配详解

@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)

可以发现,一个条件装配使用了这个类,该注解的含义是当上下文中有Marker实例时,进行注解所在配置类的装配,也就是 EurekaServerAutoConfiguration

通过查看其源码,可以看到大量的EurekaServer相关Bean声明,也就是说,实现了EurekaServerAutoConfiguration的装配,也就实现类EurekaServer的装配

好的,思路清晰了 通过@EnableEurekaServer来导入EurekaServerMarkerConfiguration,进而将内部类Marker实例化到spring上下文中,通过条件装配,再来装配EurekaServerAutoConfiguration配置文件

也就是说 内部类Marker 起到了一个开关的作用

接下来只剩最后一个问题,我们只写了一行代码,也就是 @EnableEurekaServer 加到了springboot启动类上,那么 EurekaServerAutoConfiguration 是怎样被识别并导入到我们自己的项目中呢?

涉及到另一个知识点 spring.factories 它可以实现,将我们编写的jar包中的配置类,能够被依赖方识别到。

关于这点请自行百度查阅前置知识,只要理解它的作用,代码其实很简单。关于这点多说一下,许久之前我曾经有过疑惑,就是我编写的Common包其中包含了使用spring注解@Component、@Service、@Controller等修饰的Bean,那么引入这个jar包的spring工程,如何能够将

这个Bean注入到spring上下文中呢,使用@ComponentScan扫描,显然勉强能够实现,但是如果所有引入的工程都去改写@ComponentScan 显然不现实,spring.factories就可以灵活的实现该需求,自动的将配置进行导入

@EnableWebConfigure

@EnableWebConfigure 是我自定义的注解,期望用它来自动开启Web相关的公共能力,实现如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(WebMarkerConfiguration.class)
public @interface EnableWebConfigure {
}

注解标识在启动类上即可,它并没有属性和方法,仅导入了另一个配置类 WebMarkerConfiguration.class

@Configuration
public class WebMarkerConfiguration {
   @Bean
   public Marked createMarkedInstance(){
       return new Marked();
   }
   class Marked{
   }
}

可以看到,我很懒,连名字都跟EurekaServer中的实现一样&hellip;

而引用此Marked标识的是配置类 InternalCommonBeanConfiguration

@Configuration
@Import({WebConfig.class, WebMvcConfig.class})
@ConditionalOnBean(WebMarkerConfiguration.Marked.class)
public class InternalCommonBeanConfiguration {
   @Bean
   public GlobalExceptionInterceptor createGlobalExceptionInterceptor(){
       // 全局异常处理
       return new GlobalExceptionInterceptor();
   }
   @Bean
   public TransIdFilter createTransIdFilter(){
       // TraceId 过滤器
       return new TransIdFilter();
   }
}

类中除了声明GlobalExceptionInterceptor以及TransIdFilter,还导入了@Import({WebConfig.class, WebMvcConfig.class}) 这两个类用来配合@ResponseBody或者@RestController实现JSON序列化

最后,通过在internal-common工程resource文件下,新建 META-INF/spring.factories 文件,来暴露InternalCommonBeanConfiguration,以方便其他项目能够在依赖时,自动导入。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  org.sun.online.internalcommon.configure.InternalCommonBeanConfiguration

具体工程中的应用请见 org.sun.online.serviceverificationcode.ServiceVerificationCodeApplication

设计价值

依赖方:后续的Web服务工程中,只需要@EnableWebConfigure 即可获得相应的通用能力

被依赖方:通过拓展 InternalCommonBeanConfiguration 即可令所有依赖方无需代码改动直接获得支持,方便升级维护

来源:https://blog.csdn.net/qq_41788977/article/details/125120962

标签:Java,@EnableEurekaServer,自动装配
0
投稿

猜你喜欢

  • 深入HRESULT与Windows Error Codes的区别详解

    2023-10-16 15:19:42
  • Winform利用分页控件实现导出PDF文档功能

    2023-08-11 10:15:04
  • Android Studio真机无线连接USB设备调试运行详解流程

    2023-12-13 00:37:37
  • android TextView实现跑马灯效果

    2023-07-27 16:35:31
  • WPF开发之实现一种三轴机械手控件

    2021-10-29 19:16:29
  • Android通过自定义View实现随机验证码

    2022-10-24 07:16:19
  • Java实现将图片上传到webapp路径下 路径获取方式

    2023-07-10 12:44:13
  • Android运用BroadcastReceiver实现强制下线

    2021-07-20 19:49:29
  • Flutter开发技巧ListView去除水波纹方法示例

    2021-12-27 14:15:24
  • C#设置与获取环境变量的方法详解

    2021-09-03 20:55:29
  • 新手初学Java流程控制

    2023-08-23 08:12:34
  • SpringData JPA中@OneToMany和@ManyToOne的用法详解

    2021-10-01 00:49:10
  • java中的实体类时间格式化

    2022-05-18 02:18:19
  • C# goto语句的具体使用

    2021-07-22 22:26:22
  • .NET企业级项目中遇到的国际化问题和解决方法

    2022-12-03 08:18:06
  • mvn中dependencyManagement的使用详解

    2021-11-05 10:19:20
  • Android仿360悬浮小球自定义view实现示例

    2021-10-22 10:16:14
  • Java 栈与队列超详细分析讲解

    2023-08-15 01:09:07
  • Java实现石头剪刀布小游戏

    2023-02-25 22:41:29
  • C#语法新特性之元组实例详解

    2022-09-20 03:05:53
  • asp之家 软件编程 m.aspxhome.com