📜 ⬆️ ⬇️

Writing your spring-boot-starter

Most java-developers have already become acquainted with the Spring Boot project, which allows you to quickly write an application that uses various components of the Spring Framework (Spring MVC, Spring Data and many others).

All the convenience of Spring Boot is based on the use of so-called Starters , which allow you to get a set of configured bins ready for use and available for configuration via properties files. But what to do, if for the necessary technology the starter is not written yet?

In this article I would like to talk about how starters are created using the example of a starter for Spring-social-vkontakte. Spring Social is one of the modules of the Spring Framework used to integrate with social networks. The Spring Boot project included starters for social networks such as Facebook (spring-boot-starter-social-facebook), Twitter (spring-boot-starter-social-twitter) and LinkedIn (spring-boot-starter-social-twitter), based on the use of appropriate social modules. Most developers from the CIS are primarily interested in the social network Vkontakte, for which there is a third-party module spring-social-vkontakte . Accordingly, there is no starter for this module yet. Writing this starter we will do in this article.

The cornerstone of the Spring Boot infrastructure is the AutoConfiguration classes that Spring Boot finds when it starts the application and uses it to automatically create and configure bins.
')
Let's create this class for our starter:

@Configuration @ConditionalOnClass({SocialConfigurerAdapter.class, VKontakteConnectionFactory.class}) @ConditionalOnProperty(prefix= "ru.shadam.social-vkontakte", name = { "client-id", "client-secret"}) @AutoConfigureBefore(SocialWebAutoConfiguration.class) @AutoConfigureAfter(WebMvcAutoConfiguration.class) public class VKontakteAutoConfiguration { } 

We use annotations to tell SpringBoot that our class is a configuration (@Configuration), annotations to specify the conditions under which our AutoConfiguration will be used to create bins, as well as annotations to indicate what our autoconfiguration takes place in the application initialization procedure.

In this way:

 @ConditionalOnClass({SocialConfigurerAdapter.class, VKontakteConnectionFactory.class}) 

means that the bins will be created if the SocialConfigurerAdapter (included in the Spring-Social module) and VKontakteConnectionFactory (included in the Spring-Social-Vkontakte module) are present in the classpath. Thus, without the dependencies necessary for our starter, no bins will be created.

 @ConditionalOnProperty(prefix= "ru.shadam.social-vkontakte", name = { "client-id", "client-secret"}) 

means that bins will be created only if the property is available ru.shadam.social-vkontakte.client-id and ru.shadam.social-vkontakte.client-secret.

 @AutoConfigureBefore(SocialWebAutoConfiguration.class) @AutoConfigureAfter(WebMvcAutoConfiguration.class) 

means that our bin will be initialized after WebMvc and before SocialWeb. This is necessary so that by the time SocialWeb is initialized, our bins have already been registered.

We now turn to what we will configure the bins in our AutoConfiguration.

VKontakteAutoConfiguration.java
 @Configuration @ConditionalOnClass({SocialConfigurerAdapter.class, VKontakteConnectionFactory.class}) @ConditionalOnProperty(prefix= "ru.shadam.social-vkontakte", name = { "client-id", "client-secret"}) @AutoConfigureBefore(SocialWebAutoConfiguration.class) @AutoConfigureAfter(WebMvcAutoConfiguration.class) public class VKontakteAutoConfiguration { @Configuration @EnableSocial @EnableConfigurationProperties(VKontakteProperties.class) @ConditionalOnWebApplication protected static class VKontakteConfigurationAdapter extends SocialConfigurerAdapter { @Autowired private VKontakteProperties properties; @Bean @ConditionalOnMissingBean @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES) public VKontakte vkontakte(ConnectionRepository repository) { Connection<VKontakte> connection = repository.findPrimaryConnection(VKontakte.class); if (connection != null) { return connection.getApi(); } return new VKontakteTemplate(this.properties.getClientId(), this.properties.getClientSecret()); } private ConnectionFactory<?> createConnectionFactory() { return new VKontakteConnectionFactory(this.properties.getClientId(), this.properties.getClientSecret()); } @Override public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) { connectionFactoryConfigurer.addConnectionFactory(createConnectionFactory()); } } } 


We extend the SocialConfigurationAdapter , which is needed to register our ConnectionFactory . For this, the SocialConfigurerAdapter has a callback method:

 addConnectionFactories(ConnectionFactoryConfigurer, Environment) 

We will override it by adding our ConnectionFactory.

We will also register the request-scoped bin Vkontakte , which is an interface for accessing the Vkontakte API. In this case, if the user is authorized through the application, then the interaction operation with the API will be performed using auth_token.

Consider also the VkontakteProperties class, which is used to get the configuration from the application properties files.

VkontakteProperties.java
 @ConfigurationProperties(prefix = "ru.shadam.social-vkontakte") public class VKontakteProperties { private String clientId; private String clientSecret; public String getClientId() { return clientId; } public void setClientId(String clientId) { this.clientId = clientId; } public String getClientSecret() { return clientSecret; } public void setClientSecret(String clientSecret) { this.clientSecret = clientSecret; } } 


For receiving values ​​from the properties of files, the following is responsible:

 @ConfigurationProperties(prefix = "ru.shadam.social-vkontakte") 

She tells SpringBoot to try all the properties starting with the prefix ru.shadam.social-vkontakte in the appropriate fields of the class.

Our final step is to create a file that allows the SpringBoot to find our AutoConfiguration class. For this, there is a special spring.factories file that needs to be placed in the META-INF folder of the resulting jar file.

In this file we need to specify our AutoConfiguration-class.

 org.springframework.boot.autoconfigure.EnableAutoConfiguration=ru.shadam.spring.boot.vkontakte.VKontakteAutoConfiguration 

Now, by connecting the resulting jar to our Spring Boot project and setting it in the configuration ru.shadam.social-vkontakte.client-id and ru.shadam.social-vkontakte.client-secret, we’ll get the configured / connect / vkontakte and Bin Vkontakte, which we can use to access the Vkontakte API.

Used materials:

  1. docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
  2. Link to the project on github: github.com/saladinkzn/social-vkontakte-spring-boot-starter

Source: https://habr.com/ru/post/275337/


All Articles