Case
Function:
You need to write a build that reports data to Kafka.
When the build starts, you need to set up the following resources:
1, establish several connections with Kafka
2, start a thread pool
3, start escalation of a buffer
The problem is as follows:
1, how to introduce the component in spring project and inject it into the spring container
2, such as indirectly referenced to this jar package (if the referenced project has a reference to this build jar), or just want to use the data type inside, do not intend to use the function, how to avoid the resource will be started as a result of the introduction of resources waste
3, how the configuration of the build unified management problem
4, how to manage a large number of jar package dependencies, such as the development of this build to use the Kafka 0.11.0.2, one day need to upgrade to 1.0.0
These problems actually have a good solution in spring cloud, such as Zuul, and the following is the imitation Zuul solution
first, how to make the formation be introduced by spring project
SPI mode,
such as the passage of Zuul
\meta-inf\spring.factories
To introduce, specify the boot directory
org.springframework.boot.autoconfigure.enableautoconfiguration= Org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration, Org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration
The formation is also defined as follows
\meta-inf\spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zhenai.security.report.SecurityAutoConfiguration
In Securityautoconfiguration, the bean is initialized as needed, and the associated resource is started. such as starting a connection, starting the local thread pool, etc.
But the problem here is that as long as the jar package is introduced (including the introduction of the jar), then all the projects will be connected to Kafka to start some useless thread pool.
two, how to block indirectly referenced to this JAR package project launch related resources
To solve this problem, spring cloud and spring boot are slightly different, look at Spring Cloud first.
Marker Way
Spring Cloud Tag Mode
First look at Zuul is how to do, if you want to start Zuul in the project, will generally add @enablezuulproxy tag in the main class, as follows:
@SpringBootApplication @enableeurekaclient@enablezuulproxy Public class Application {... ....}
Need to introduce @enablezuulproxy tags
@EnableZuulProxy source code is as follows: @EnableCircuitBreaker @enablediscoveryclient@target (Elementtype.type) @Retention ( Retentionpolicy.runtime) @Import (zuulproxymarkerconfiguration.class) public @interface Enablezuulproxy {}
Seeing @Import (Zuulproxymarkerconfiguration.class), zuulproxymarkerconfiguration only did one thing, introducing a maker tag
As follows:
@Configuration Public class zuulproxymarkerconfiguration { @Bean public Marker Zuulproxymarkerbean () { return New Marker (); } class Marker { }}
This maker object is used as a startup to enable the configuration, which controls whether the resource is started, such as Zuulserverautoconfiguration
@Configuration @enableconfigurationproperties ({zuulproperties. class }) @ConditionalOnClass (Zuulservlet. class ) @ConditionalOnBean (zuulservermarkerconfiguration.marker. class )// Make sure to get the serverproperties from the same place as a normal web app would@Import ( Serverpropertiesautoconfiguration. class publicclass zuulserverautoconfiguration {... ...}
Whether or not the marker is injected into the related class, is started.
So
Here, the components in the case are also chosen in this way, such as
@EnableZASecurityReport tags
When you need to start, add tags to the main class, such as
@EnableZASecurityReportpublic class Application {... ....}
Subsequent Kafka of the connection class, thread pool, buffer, and so on can be managed according to the relevant identity, such as the SPI entry class Securityautoconfiguration:
@Configuration @enableconfigurationproperties ({securityreportproperties. class }) @ConditionalOnBean (Securityproxymarkerconfiguration.marker. class publicclass securityautoconfiguration {... ... }
Thus, if in the main startup class, as long as the @enablezasecurityreport is not joined, the associated resources will not be started even if the component's jar package is introduced.
Starter Way
There is another way, that is, spring boot uses a much more start way
All of the spring boot configuration is in Spring-boot-autoconfigure/meta-inf/spring.factories, which determines whether to start the resource by @conditionalonbean the specific class is introduced.
such as: Spring-boot-starter-data-redis
First, the boot class of Redis is introduced through spring.factories
Org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration, Org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration, Org.springframework.boot.autoconfigure.data.redis.redisrepositoriesautoconfiguration,\
Such as:
Redisautoconfiguration
@Configuration @conditionalonclass ({redisoperations. class }) @EnableConfigurationProperties (redisproperties. class ) @Import ({lettuceconnectionconfiguration. class, Jedisconnectionconfiguration. class })publicclass redisautoconfiguration {...}
When a project needs to use Redis, the related classes are introduced through MAVEN
<dependency> <groupId>org.springframework.boot</groupId> <artifactId> Spring-boot-starter-redis</artifactid> </dependency>
Spring-boot-starter-data-redis, in fact, is an empty project, there is a spring.provides, through it introduced Redis-related jar package, and then make @conditionalonclass effective, This completes the initialization of the Redis jar environment.
Third, configure how to manage issues uniformly
A component (Jar package) comes out, the configuration will be more, such as the project involves Kafka configuration, thread pool configuration and so a lot of, the traditional way is to write a related document, a bunch of configuration items will make it very cumbersome to use.
1, the Convention is better than the configuration
In spring Cloud/boot, the most useful thing is that the convention is better than the configuration. Remember conventions, write less configuration
As in Zuul, you only need to configure several required items, others are contract items
For example, the contract configuration file is application.yml (or bootstrap.yml):
Zuul:debug: routes: zhenai-CLIENT: /test/**
Simple configuration under routes can be started, if you want to find the Zuul configuration of the contract value, you can directly look for the general configuration class Zuulproperties,
Zuulproperties, which contains all the configuration items, is divided into modules by configuring the object as follows:
Zuulroute related, host related, hystrixsemaphore related, etc.
(also a default convention)
So
In the assembly, it is also possible to imitate the simplified configuration. The core function of this component is to escalate, histograms project should be only Kafka address, to enable, only need
report.kafkaconfig.servers=x.x.x.x:9092
You can, for detailed configuration, and a fixed value, with a unified configuration file tube Reportproperties.java
It indicates the value of the agreed configuration.
2, using spring's automatic assembly function
Automatic assembly using the @configurationproperties label. This all basic function is not elaborate.
View zuulproperties in detail.
The advantage is:
1, can realize dynamic configuration, such as configuration map,list, even enums, etc.
2. Dynamic hot update is possible with Spring Cloud Config
Four, unified management of the jar package dependencies
In the spring cloud/boot, jar files are managed separately in spring-boot-dependencies projects, while compatibility between versions relies on open source projects Http://platform.spring.io/platform /To do management, so there are very few version conflicts.
As a self-developed component, it is best to rely on the third-party jar is the spring boot to the same management version number, and need to use the other jar, can be used to set up a dependencies project alone to manage, no longer the project can write version number, convenient for unified upgrade maintenance.
Summary below:
1, how to provide components to the Spring/spring boot project will be better
Use SPI to facilitate smooth referencing
2, how to avoid a project that does not need to use the component to mistakenly refer to the jar, automatically start component-related resources
1, provide @enablexxx tag mode, inject a marker tag, judge by @conditionalonbean at startup
2,starter mode, configuration and class separate, @ConditionalOnBean to judge, while the reference is started will
3, how the configuration of the components is managed uniformly
1, the Convention is larger than the configuration, simplifying the configuration. Unify the Xxxproperties.java of one component for each component and provide a contract value
2, automatic assembly mode
4, how to manage jar package uniformly, prevent jar version conflict, etc.
To spring Boot unified management, the other version number unified in the parent project (or join the Dependencies Project) management version
Add an advertisement, the New Year, intends to maintain the public number, quality.
Welcome to the attention, thank you
and spring Cloud/boot Learn how to manage your own components