@EnableEurekaServer注解
@EnableEurekaServer
1.1 在项⽬启动类上使⽤@EnableEurekaServer,可以将项⽬作为SpringCloud中的注册中⼼。那么这个注解做了哪些事呢?
1.2 点进去@EnableEurekaServer 这个注解,可以看到介绍时是这样的:
Annotation to activate Eureka Server related configuration {@link EurekaServerAutoConfiguration}(激活Eureka服务器相关配置EurekaServerAutoConfiguration的注释)
可以将@EnableEurekaServer 这个注解看作是⼀个开关,开启时,会激活相关配置,会作为注册中⼼。同时,他⼜引⼊了EurekaServerMarkerConfiguration类。
1.3 点进去EurekaServerMarkerConfiguration这个类,可以看到介绍是这样的:
Responsible for adding in a marker bean to activate {@link EurekaServerAutoConfiguration}。(负责添加⼀个标记来激活配置类EurekaServerAutoConfiguration)
这个类中,向容器注⼊了⼀个类EurekaServerMarkerConfiguration.Marker,作⽤就是激活配置类。源代码是这样的:英语三级考试成绩查询
mcgrady
@Configuration
public class EurekaServerMarkerConfiguration {
@Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
}
class Marker {
}replaceall
}
1.4 下⾯来看配置类EurekaServerAutoConfiguration。这个类上⾯有三个⽐较重要的注释:
@Configuration
@Import(EurekaServerInitializerConfiguration.class)
niveau@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
@EnableConfigurationProperties({ EurekaDashboardProperties.class,
InstanceRegistryProperties.class })
@Configuration注解表⽰这是⼀个配置类,通过@Bean注解声明⼀些注⼊到Spring IOC容器中的Bean。
@Import(EurekaServerInitializerConfiguration.class)注解表⽰它导⼊了EurekaServerInitializerConfiguration这个类。
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)注解表⽰只要Spring容器中有EurekaServerMarkerConfiguration.Marker.class类的实例存在,那么就会将这个EurekaServerAutoConfiguration也注⼊到Spring 容器中。
@EnableConfigurationProperties注解 将EurekaDashboardProperties和InstanceRegistryProperties对应的配置属性类注⼊容器中
查看EurekaServerAutoConfiguration的源代码,可以发现它向Spring容器中注⼊了⼀些bean。举⼏个例⼦:
这个bean中保存了这个实例的⼀些信息,名称为"Eureka Server"
@Bean
public HasFeatures eurekaServerFeature() {
return HasFeatures.namedFeature("Eureka Server",
EurekaServerAutoConfiguration.class);
}chakrit
//matchIfMissing属性表⽰缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错
/
/这个是仪表盘相关的Bean
@Bean
@ConditionalOnProperty(prefix = "eureka.dashboard", name = "enabled", matchIfMissing = true)
public EurekaController eurekaController() {
return new EurekaController(this.applicationInfoManager);
}
这两个实例来⾃comflix.eureka,将相应的处理逻辑交到comflix.eureka中,它们接⼿了真正的EurekaServer的启动逻
辑,SpringCloud 只是在容器中将这些Bean初始化。
//
@Bean
public EurekaServerContext eurekaServerContext(ServerCodecs rverCodecs,
PeerAwareInstanceRegistry registry, PeerEurekaNodes peerEurekaNodes) {
return new DefaultEurekaServerContext(this.eurekaServerConfig, rverCodecs,
registry, peerEurekaNodes, this.applicationInfoManager);
}
@Bean
public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry,
EurekaServerContext rverContext) {
return new EurekaServerBootstrap(this.applicationInfoManager,
this.eurekaClientConfig, this.eurekaServerConfig, registry,
rverContext);
}
向容器中初始化⼀个Jery 过滤器。
tips:使⽤FilterRegistrationBean向Spring中注册过滤器⼗分⽅便。
@Bean
public FilterRegistrationBean jeryFilterRegistration(
javax.Application eurekaJeryApp) {
FilterRegistrationBean bean = new FilterRegistrationBean();
indicates
bean.tFilter(new ServletContainer(eurekaJeryApp));
bean.tOrder(Ordered.LOWEST_PRECEDENCE);
bean.tUrlPatterns(
Collections.singletonList(EurekaConstants.DEFAULT_PREFIX + "/*"));
return bean;
}
1.5 现在,在回过头来看⼀下配置类EurekaServerAutoConfiguration导⼊的EurekaServerInitializerConfiguration
这个类。
⾸先可以发现它使⽤了@Configuration注解。然后实现了ServletContextAware, SmartLifecycle, Ordered三个接⼝,实现了这些接⼝的⽅法。
@Override
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//TODO: is this class even needed now?
log.info("Started Eureka Server");
publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));
EurekaServerInitializerConfiguration.this.running = true;
publish(new EurekaServerStartedEvent(getEurekaServerConfig()));
}
catch (Exception ex) {
// Help!
<("Could not initialize Eureka rvlet context", ex);
}
}
}).start();
}
private EurekaServerConfig getEurekaServerConfig() {
return this.eurekaServerConfig;
}
private void publish(ApplicationEvent event) {
this.applicationContext.publishEvent(event);
}
@Override
public void stop() {
this.running = fal;
}
上⾯代码主要实现了start() 和 stop()⽅法。这两个⽅法的主要作⽤是初始化rvlet相关上下⽂,在start的时候调⽤tInitialized,在stop的时候调⽤tDestroyed,都是借助eurekaServerBootstrap类来实现,⽽eurekaServerBootstrap⾥头部分调⽤了EurekaServerContext。再来看EurekaServerBootstrap中contextInitialized()⽅法的代码:
public void contextInitialized(ServletContext context) {
try {
initEurekaEnvironment();
initEurekaServerContext();
context.tAttribute(Name(), this.rverContext);
}
catch (Throwable e) {雅思考试报名费
<("Cannot bootstrap eureka rver :", e);
throw new RuntimeException("Cannot bootstrap eureka rver :", e);
}
}
protected void initEurekaEnvironment() throws Exception {
log.info("Setting the eureka configuration..");残灯末庙的意思
String dataCenter = ConfigInstance()
.getString(EUREKA_DATACENTER);
if (dataCenter == null) {
log.info(
"Eureka data center value eureka.datacenter is not t, defaulting to default");
冬天的英文.tProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT);
}
el {
.tProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter);
}
String environment = ConfigInstance()
.getString(EUREKA_ENVIRONMENT);
if (environment == null) {
.tProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
log.info(
"Eureka environment vironment is not t, defaulting to test");
}
el {
.tProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, environment);
}
}
protected void initEurekaServerContext() throws Exception {
// For backward compatibility
XStream.PRIORITY_VERY_HIGH);
XStream.PRIORITY_VERY_HIGH);
if (isAws(Info())) {
this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig,
this.eurekaClientConfig, istry, this.applicationInfoManager);
this.awsBinder.start();
}
EurekaServerContextHolder.initialize(this.rverContext);
log.info("Initialized rver context");
// Copy registry from neighboring eureka node
int registryCount = istry.syncUp();
// Register all monitoring statistics.
}
主要是调⽤了initEurekaEnvironment()和initEurekaServerContext()⽅法,来初始化环境配置和初始化上下⽂。可以看到initEurekaEnvironment()是设置了⼀些属性值,在initEurekaServerContext()⽅法中主要调⽤了
curableEurekaServerContextHolder.initialize(this.rverContext),istry.syncUp(),
EurekaServerContextHolder.initialize(this.rverContext),istry.syncUp()主要是给⾮IOC容器引⽤EurekaServerContext,registry.syncUp()从其他eureka rver获取实例信息,然后注册到本rver,然后复制到其他rver节点上。registry.openForTraffic()标识⾃⾝rver的状态为UP,表⽰可以开始接收请求。