I am a python dev and totally new to Spring boot and gradle. However i am fine with java and Trying my best with Kotlin. I was trying to run Spring Boot application(Kotlin) on localhost. Gradle build is working fine except these line
#Configuration
#AutoConfigureAfter(DispatcherServletAutoConfiguration::class)
open class Assembly : WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter()
{
.
.
No value passed for parameter resourceProperties, mvcProperties, beanFactory....
I understand that WebMvcAutoConfigurationAdapter constructor expects these params but should they not be passed automatically through annotation #Configuration and #AutoConfigureAfter .
As i am totally new to spring boot i have no idea what is going wrong and where. As this code is already running in production so i am really confused about whether i am missing some local configuration or gradle conf or something else.
WebMvcAutoConfigurationAdapter isn't intended to be used directly by application code. You should be extending WebMvcConfigurerAdapter instead.
I suspect you've upgraded to Spring Boot 1.4. In that release, WebMvcAutoConfigurationAdapter changed from using field injection to constructor injection. This means that subclasses now need to call the super-constructor passing in the required arguments.
#AutoConfigureAfter only controls the ordering of auto-configuration classes and has no effect on dependency injection. It also only affects auto-configuration classes so may we'll be doing nothing on your Assembly class.
#Configuration doesn't really affect dependency injection either. Configuration classes can have dependencies injected, either into fields annotated with #Autowired or into their constructor. Previously, that constructor also had to be annotated with #Autowired but, as of Spring Framework 4.3 (Spring Boot 1.4), the annotation is unnecessary if the class has a single constructor.
Related
I have dependency in my spring boot project which fetches values of some properties using Spring's EnvironmentPostProcessor.
Now these properties are database credentials and not everyone has access to the credential since there is no dev environment for the db in question. I just want to change the configuration that the credentials don't get fetched on dev or local environment on application startup as that would result in a error and the application will fail to start.
Class A implements EnvironmentPostProcessor{}
I tried to use #Lazy annotation on the Class Annoteted with #ConfigurationProperties. I also tried using my own BeanFactoryPostProcessor (with #Order(HighestPrecedence) to programmatically set the A to lazy load, but it gets called before my BeanFactoryPostProcessor's postProcessBeanFactory method.
Is what I'm trying to achieve possible and am I going about it the wrong way?
#Lazy is only to be used with #Bean or #Component (Or any #Component-based annotations ex. #Service)
Take note: You can also add it to a #Configuration class, but that just means that all Beans in the class are annotated with #Lazy
#Lazy is a bit of a weird annotation in general; it should be seen as an IF possible then lazy load. If some other bean needs the lazy bean, the lazy bean will be initialized. (It's like the Pirate code, more of a guideline than an enforced rule)
Finally, marking #ConfigurationProperties with #Lazy seems a bit odd. As Spring will need these Configuration property "beans" to create the Spring Context.
However, the common use case for #Lazy is a failing database connection, preventing the application from starting. See the question if that is what you are running into.
Summary:
You can configure your repositories to be lazy-loaded with:
spring.data.jpa.repositories.bootstrap-mode=lazy
Last remark (Me just guessing)
If you wish to change properties once your application is already running, I would look at the following tutorial. It goes into manually reloading configuration and also #RefreshScope.
According to documentation EnvironmentPostProcessors must be registered via META-INF/spring.factories:
Allows for customization of the application's Environment prior to the
application context being refreshed. EnvironmentPostProcessor
implementations have to be registered in META-INF/spring.factories,
using the fully qualified name of this class as the key.
Implementations may implement the Ordered interface or use an #Order
annotation if they wish to be invoked in specific order.
I have a common project I'd like to import to both a spring boot application and a J2EE application. One of the Objects is a set of attributes set from parameters. In spring boot I'd like to use #Value to set them, for the non-spring platform I have to load the properties with code. I'd like to use the same object for both environments since it's use is pervasive. My attempts to use builders have failed because they inevitably get instantiated before the spring objects.
Who's done this?
Thanks in advance
I'd hoped for something more elegant but maybe I'm spoiled by Spring Boot. I had to replace the #Autowired parameters class with a builder that implements ApplicationContextAware. The setApplicationContext method will instantiate the parameters object if it gets executed (the builder class was loaded by Spring and is aware) or by the simple retrieval of parameters for a non-spring environment.
I am using a spring boot 1.5.4 project where I need a clarification on testing package.
I am seeing Spring Boot comes with #MockBean which is part of org.springframework.boot.test.mock.mockito package.
My question is - Is it similar to Mockito external dependency and I can avoid using Mockito as external dependency as spring boot mock.* package has all features which Mockito has?
As already pointed in Greg's answer , mockito core is already included in spring-boot-starter-test so its already there in your project, no external dependency is needed.
Having said that - mockito's #Mock and Spring's #MockBean are a bit different in a way that #MockBean is basically a #Mock plus #Bean so it does what mockito annotation does plus it works with like a bean too i.e. it places instances in Spring's application context and all other spring bean related concepts come into picture too.
From documentation -
Annotation that can be used to add mocks to a Spring
ApplicationContext. Can be used as a class level annotation or on
fields in either #Configuration classes, or test classes that are
#RunWith the SpringRunner.
Mocks can be registered by type or by bean name. Any existing single
bean of the same type defined in the context will be replaced by the
mock, if no existing bean is defined a new one will be added.
When #MockBean is used on a field, as well as being registered in the
application context, the mock will also be injected into the field.
For non - Spring applications where DI & context are not there, you shoudl use #Mock and for Spring apps , you should use #MockBean.
If you look at the dependencies for spring-boot-starter-test, you'll see that it depends on the Mockito library so it is included for you.
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.
I am using autowiring in one of my projects. #autowiring is working fine in the controller, but I need to use same autowiring object in some other class, which is used as task class for quartz. Autowiring is not working there.
I tried this code listed below, but it did not succeed. In all attempts it's getting null for readXmlDao.
#Repository("updateTeam")
public class TeamUpdate {
#Autowired
#Qualifier("readXmlDao")
ReadXmlDao readXmlDao;
Please suggest a solution, thanks.
Autowire works in spring context (class instances managed by spring). Quartz creates its own contexts (creates its own instances). Spring do not have to know about these classes and its why autowires not working on them.
It is more spring/quartz configuration issue, than class annotation issue.
Spring will never leave an #Autowired target null. If it's processing the bean and can't find a match it will throw exceptions.
Since you are telling us it's null, the only possibility is that Spring is not managing your object. You're either creating a TeamUpdate object manually or some other process (not Spring) is creating it for you.
In your spring-servlet file make sure you are scanning the correct packages.
<context:component-scan base-package="your package here"/>
A lot of times you might have your controllers and your repositories in different packages. Make sure to scan both.
you might want to try this approach for using spring managed beans in a non-spring managed object.
http://www.javacodegeeks.com/2015/03/using-spring-managed-bean-in-non-managed-object.html