Spring boot FF4j ff4j-spring-boot-starter excluding swagger doc - java

I need in my spring boot application FF4j. I try
<dependency>
<groupId>org.ff4j</groupId>
<artifactId>ff4j-spring-boot-starter</artifactId>
<version>1.8</version>
</dependency>
and in this case my application is broken because of swagger.
can I exclude org.ff4j.spring.boot.web.api.config.SwaggerConfig from my configuration?
I tried to manage it but cant reach final solution because of new different issues.

In case you configure swagger in your application in usual case it will be failed because of different reasons. Possible next ones:
spring needs resolve which swagger bean should be used;
cg-lib conflict in case you used bean name api;
swagger conflict because two different Docket beans in same spring context;
Firstly I tried to exclude ff4j-spring auto configuration configuring steps in similar way but excluding swagger for example. Application can't start ff4j without their swagger. That's confused a lot.
Looking different solutions I tried follow some recommendations like but I'm getting different issue with missed class for my application. Missed class is in thymeleaf5. I can't use thymeleaf5 because of it uses same name interface but different arguments. Additional workarounds make my application failed because of hibernate.
Swagger solution is:
in your configuration inject swagger Docket from ff4j:
#Autowired
Docket api;
and rewrite api with your configuration in #PostConstruct block. This solution is not elegant, but provides fix for swagger configs.
#PostConstruct
public void reconfigureSwagger() {
api....
}
P.S.
After swagger issue I've got more unresolved elements (but that's will be a different questions).
P.S.2.
FF4j library provides great UI and ideas and this is general reason why I do not avoid of its headache.

Related

How to avoid putting #RefreshScope on multiple beans in my application

We are externalizing configuration of our microservices (spring boot based) using spring cloud.
As per my understanding on Spring Cloud, to enable the beans loading refreshed/updated values from Config server we need to do 2 things in Spring Cloud Client:
add #RefreshScope on the beans reading values from property files
using #Value
add spring actuator to provide /refresh endpoint to
refresh the context.
Scenario:
We have 100s of classes reading values from property file using #Value.
I have to mark all these beans refresh enabled using #RefreshScope annotation.
How can I avoid putting #RefreshScope annotation on all these classes.
Is there any shortcut or spring cloud feature to get around this situation.
You may want to look into Spring Boot feature called #ConfigurationProperties. It is designed to better organize several external configuration options.
According this Github issue, it should work for spring-cloud without #RefreshScope usage.
EDIT (reaction on comment): Maybe you are missing point of #ConfigurationProperties. With this annotation, you wouldn't use it in other configuration classes. You would have dedicated class (or few classes) only for reading and providing properties. Other configuration classes would inject this configuration holder bean.
You could encapsulate your #Values into one (or several) ConfigurationService bean which is #RefreshScoped and autowire this service into your classes instead. That way you only have a small amount of request scoped beans and your services can stay singletons.

Spring Boot: Determining what autoconfiguration are applied to jersey?

Following the online docs for adding jersey to Sring boot, it appears I just need to include the following package
spring-boot-starter-jersey
Actually, it states that Spring Boot provides automatic configuration by including this package.
Where can I find out what exactly is happening?
If I don't add this package then what is NOT configured?
I tried searching for the package in google but got no specific explanation only saying that it automatically configures, but configures what?
I would like to know a little more of what is happening behind the scenes.
All of the auto-configuration code for all that Spring Boot supports is in the spring-boot-autoconfigure module. If you look through the packages, you will see a jersey package.
The "starter" modules generally do not have any code (of course unless it is a third-party module). How it works is that the code in the auto-configuration has some annotations that are #ConditionalOnXxx, where the condition be anything from a class being on the classpath. If this class is not available, then the auto-configuration will not take place. That's pretty much all adding the jersey starter module does: it adds the jersey dependencies so that the auto-configurer will applied.
Now what exactly is being auto-configured specifically for Jersey? Check out the source for the JerseyAutoConfiguration. Basically what you are going to see is your ResourceConfig being injected into the configurer. From that ResourceConfig, it creates Jersey's ServletContainer (which is the main entry point for Jersey.
Then, depending on our properties configuration, either a FilterRegistrationBean or a ServletRegistrationBean is created as a Spring bean, wrapping Jersey's ServletContainer. Jersey can be created as a Servlet or a Servlet Filter. Whichever one we configure we be used.
And that's it for the Jersey configuration. Spring Boot will get a servlet container (e.g. Tomcat, Jetty) from some other auto-configuration, and take the Filter/ServletRegistrationBean and add the Servlet/Filter to that servlet container.
Also, not really that important, but the auto-configuration also give us some Jackson configuration helpers. For example, instead of configuring our own ContextResolver, we can just configure an ObjectMapper Spring bean.
That's really all you get. It's nothing so spectacular that you couldn't just do it yourself without depending on the auto-configuration.
I would recommend learning a little more about how Spring Boot works to provide the automatic configuration in general.
A good reference is the spring boot reference guide. http://docs.spring.io/spring-boot/docs/1.5.3.RELEASE/reference/htmlsingle/#common-application-properties
You can look at the common application properties in appendix A to see what all spring allows you to configure out of the box.
The Reference guide also gives a high level of what "spring-boot-starter-jersey" if you search for it on the page.
They also have a few samples that you can go through and debug to follow along if that is a way for you to learn.
Hope that gives you a starting point for learning!

SpringBoot application ignore xml configuration for HibernateValidator

My question is the following:
Is it possible to ignore XML configuration for HibernateValidator, i.e. exclude validation.xml parsing in a SpringBoot application?
I do not have the need for a validation.xml in my application, but I see that when the application starts up, it tries to parse this file.
I found this in the Hibernate Validator documentation (https://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/validator-xmlconfiguration.html):
It is even possible to ignore the XML configuration completely via Configuration.ignoreXmlConfiguration().
What I see is, that in the LocalValidatorFactoryBean.afterPropertiesSet() method, the configuration is created for the validator. This bean has a method called postProcessConfiguration(Configuration configuration), which is called before the validatorFactory is built from the configuration.
It seemed an ideal place to call the ignoreXmlConfiguration() method, what the documentation suggested.
I tried to extend this LocalValidatorFactoryBean, so that I can implement this call in the above mentioned method. Then I tried to load this bean via java configuration class.
Unfortunately some bootstrapping mechanism already uses the Spring provided bean, before it finds mine, the two beans run at the same time. I saw the message saying that XML configuration is ignored the with the bean I created, however, this solution did not help, because the Spring provided bean is not substituted with mine.
I also tried to find if there is any application property that I can use, or exclude some autoconfiguration, but no luck.
Any ideas? :)
UPDATE:
I tried excluding the HibernateJPAAutoConfiguration, it didn't help.
If you dont need hibernate validator then remove all dependency related to hibernate validator from pom.xml file.
you can also try #EnableAutoConfiguration(excludes=) annotation adding on your Application class to exclude default validation configuration.
like #SpringBootApplication(exclude = {HibernateJpaAutoConfiguration.class,DataSourceAutoConfiguration.class} })

How to Configure Dependency Injection in a Library Project?

How to Configure Dependency Injection in a Library Project?
Let me illustrate this question with the following example.
Maven Library Project
ReservationAPI
com.example.reservation-api
This project contains a convenience class called ReservationApiClient which uses a RestTemplate (from the Spring Framework) for making HTTP calls.
Is it possible to make the RestTemplate field #Autowired in this library project instead of instantiating it myself?
Maven Executable Project
org.company.application
This project is a Spring Boot application and uses the above ReservationAPI as a dependency. This app will create a #Bean for the convenience class ReservationApiClient contained in that library and will then execute its public methods which in turn make HTTP requests.
What is a good strategy and/or best practices for the scenario described above?
You can do this if you include autowiring in your library project although that means it would always need to be used with a Spring application context to get the value unless you also have getter/setter methods to use as well. However, I don't think using RestTemplate as an autowired object makes sense since there is nothing specific about a RestTemplate and unless you name the beans there is only one bean definition for a class. All of the methods for the RestTemplate require the URI there anyhow. So in this case I would just use the bean for your ReservationApiClient in your application.
One other way to do it is if you want to include Spring dependencies in your library (which I guess you already are by using RestTemplate) you can declare your ReservationApiClient as a #Service or #Component and then use the #ComponentScan annotation in your main Spring Boot project to search that library for components to include in the bean registry.
Another option is to use a feature like Spring Boot's Autoconfigure to create factories that use third party libraries and configure them per properties in your application settings. The auto configuration documentation would be a good place to start with this. You can see the starter projects they have on GitHub and then the associated Autoconfigure classes they have associated with these.
Let me know if any of this does not make sense.

How does the EnableAutoConfiguration spring annotation work?

I am no fan of gross over abstractions, And i think Spring has committed a major felony.
But I'm willing to overlook it this time if someone can explain the algorithm behind the 'auto' configuration.
Having a look at spring's own javadocs, It doesn't give much away other than saying that it will intelligently guess what you need and something to do about conditional beans.
Does someone know what algorithm is used to determine what needs to be loaded?
In my experience as a Spring Boot user the basic factors for Spring Boot to decide on what auto-configurations will be enabled are:
1) The classes present on the classpath. For example if RabbitMQ and Spring AMQP classes are present, then the RabbitAutoConfiguration will be enabled. The corresponding annotation is #ConditionalOnClass,
2) The presence or not of user defined beans. For example, if all the Spring Data JPA is present on the classpath, Spring Boot will register a LocalContainerEntityManagerFactoryBean bean only if the user has not already done so. The beans registered by the user will 'override' the default ones. The relevant annotation is #ConditionalOnMissingBean
As #DaveSyer mentions, you can of course use Spring Boot without #EnableAutoConfiguration if you want to include the relevant configuration on your own. Or you could use the less drastic solution of the exclude field of #EnableAutoConfiguration. If for example you want Spring Boot to autoconfigure everything except ActiveMQ, you would use #EnableAutoConfiguration(exclude=ActiveMQAutoConfiguration.class)
In my opinion, there is absolutely no felony here! You can use what you want from Spring Boot. When you don't want something it has to offer, you can easily opt out partially or completely!
Also if you want to get a look under the covers, you can add the property
logging.level.org.springframework.boot=DEBUG
to application.properties and Spring Boot will gladly give a detailed report of what was auto-configured and what wasn't
There is some documentation in the Spring Boot Reference Guide. It's not terribly complicated, and I hardly think it's a felony to just include a bunch of #Configuration that you might have written anyway (because that's all it does). Feel free not to use #EnableAutoConfiguration if you prefer to include the individual configurations individually.

Categories