Wiring a bean from dependency module - spring

I have created a configuration project which essentially creates couple of beans with configuration stereotype. Then, I want this project to be reused across by my clients.
I have added this config project as a maven dependency, but my client project is not having those beans i have created as part of configuration project.
Could someone help

Ok, the answer is the following: you should place
#ComponentScan("you.configurations.base.package")
on one of your configuration (in the current application, one that #SpringBootApplication sees) or on the class with #SpringBootApplication annotation.
The explanation is as follows: #SpringBootApplication under the hood contains #ComponentScan without specifying a base package. That means that it says to Spring to scan the package where the class annotated with #SpringBootApplication resides and all the packages recursively. And that's it. If you place you #Configuration somewhere there - it will create it during startup, otherwise not.

We can resolve this by enabling spring-boot autoconfiguration
Create classpath->resources->META-INF->spring.factories file
org.springframework.boot.autoconfigure.EnableAutoConfiguration=[add your class with you need to be loaded during application load time]

Related

Springboot build not working because of test configuration

I have started a spring boot project using start.spring.io.
But I am getting this error-
I have read various articles on the internet about this issue and they all say about putting my tests in the same package as my Main class.
But I already have the same.
Could you point out what is wrong with my configuration?
The exception is pretty clear: You are missing a configuration for your spring context. What you need to do is to add the configuration classes for your context like so:
#SpringBootTest(classes = { TestConfiguration.class })
whereas your TestConfiguration class must be annotated with
#Configuration
and/or
#EnableAutoConfiguration
There you can add configurations to your liking. You can of course also use your DatabaseApplication class as Configuration although Im wouldn't recommend that.
The search algorithm works up from the package that contains the test until it finds a #SpringBootApplication or #SpringBootConfiguration annotated class. As long as you’ve structure your code in a sensible way your main configuration is usually found.
Make Sure your DatabaseApplication class is annotated with #SpringBootApplication .

Spring AOP aspect doesn't get applied if included from an external jar with different package name

I have a spring boot rest service that included an external project in pom as it's dependency. That external project is basically a jar that has spring AOP code.
The base package in my main application that includes this external jar with spring AOP code is x.y.z
The class in external jar where the #before advice is, is under the package a.b.c
With this class under a.b.c package, it doesn't get recognized by the main application where I want to use the spring aop implementation and apply the aspect. However, when I change it's package from a.b.c to x.y.z (which I really can't do in real life) it works fine.
I know that in spring boot service which happens to be the including service, it scans everything under root package given in the application class, x.y.z in this case and that is why aspect works fine if it's class is under x.y.z.
however, the problem is that this spring app jar will be used across multiple applications. So changing package name like this is not an option.
Is there a way to accomplish this without changing the package name of the class where spring app code is ?
Probably component scan is only activated for your application class packages by default. You can extend it to multiple packages, including the aspect package:
XML style configuration:
<context:component-scan base-package="x.y.z, a.b.c" />
Annotation style configuration:
#ComponentScan(basePackages = {"x.y.z", "a.b.c"})
Disclaimer: I am not a Spring user, only an AspectJ expert. I just knew that you can configure component scan, googled the syntax for you and hope it is correct.
Please define the bean (of jar project )inside main application. Give the #ComponentScan(basePackages = {"x.y.z", "a.b.c"}) as well as #EnableAspectJAutoProxy. Also include below piece of code.
ex:
` #Bean
public LoggingHandler loggingHandler()
{
return new LoggingHandler();
}`
Also annotate external jar code with:
`#Aspect
#Component
public class LoggingHandler {`
What #kriegaex suggests is correct. In addition to that, please make sure you are using #Component along with #Aspect. Since #Aspect is not a Spring annotation, Spring won't recognize it and hence your aspect won't be registered. So, using #Component is mandatory to getting aspects to work in Spring environment.

Spring not recognising some #Configuration and #Component classes

I have - or rather had - a working Spring application, running within IntelliJ. It contains several classes annotated with #Configuration, and several #Component beans. At some point, the following happened:
Intelli started showing errors in the code editor stating "Could not autowire. No bean of 'xxx' type found". But there are such beans which are annotated with #Component.
Breakpoints in the constructor of specific #Component beans are not reached. But that is not true for all #Component beans.
When running in debug mode, breakpoints in certain #Configuration files are not reached, even though the debugger was stopping there before. The application will fail if it is autowired with one of these #Component beans.
The application starts without errors, but obviously without several beans configured in #Configuration classes being called.
The class which contains the main method which runs the Spring Boot application is annotated with #SpringBootApplication. #Component classes which live in the same package as this class are recognised and can be autowired, even into classes in other packages.
I am not aware of anything in the code or project which would have changed.
Under File -> Project Settings -> Modules, under Spring Application Context have now selected all #Configuration files. However this makes no difference.
Have also tried Build -> Rebuild Project.
The packages in which the classes reside have not changed. Has anyone seen anything like this before?
Thanks
If few classes are not getting recognised #Component. Then it could be the case that those classes don't come under the same package. You must have observed that the classes under the same package as of Main class of #SpringBootApplication, got recognised with #Component because #SpringBootApplication defines an automatic #ComponentScan on the package.
So other classes which were defined in some other package are not recognised because there is no #ComponentScan for those classes' package.
You can do the following to get those classes recognised(add the other packages which are not directly under the hierarchy of #SpringBootApplication):
#ComponentScan({"com.example.springboot.anything","com.example.springboot.somethingelse"})
#SpringBootApplication
public class AnySpringBootApplication {
I am sure it will not be a common case, but for me the problem was that my class had a relatively generic name. Although it was located in the package mentioned in the ComponentScan, on the same level with other classes all found and used, I kept having problems that the ApplicationContext failed to load. After I renamed the class it worked, I found that two other classes in org.springframework had the same name.

Spring Boot ehcache in multi maven project

Im trying to use multiple ehcahe.xml configuration files in place of modules which will use defined caches.
When is the ehcache.xml configuration placed under resources of app-web module from where the spring boot application is started it works fine with #EnableCaching.
#SpringBootApplication
#Import({ CommonApp.class, CoreConfig.class})
#EnableSwagger2
#EnableCaching
public class WebApplication extends WeblogicMvcConfigurerAdapter {
}
But when is the configuration placed under the app-core module and #EnableCaching is moved under CoreConfig which is imported by WebApplication it fails on runtime.
#Configuration
#ComponentScan
#EnableCaching
public class CoreConfig {
}
When #Cacheable method is called I'm getting
java.lang.IllegalArgumentException: Cannot find cache named 'systemParameterCache'
My idea is that every module can have own ehcache.xml configuration with the caches which belong to that module.
Is it possible to use like that? What I'm doing wrong?
Thanks!
It is possible. But I wouldn't recommend that. One cache manager in an application is enough. Having many is resource consuming for nothing. If you have trouble giving different names to your caches, I suggest that you use a module prefix.
Then, I'm not sure what you mean by modules. #EnableCaching is expected to be specified once in an application.
But if it's only specified on CoreConfig it should work. However, you still need to create systemParameterCache in your cache configuration. It seems to be your problem here.

Can I start with a spring boot application without the annotations componentscan,autoconfiguration,configuration,springbootapplication?

I have written some code in order test integration with mongoDB. Please find the link to the main method for running this spring boot application below,
https://github.com/siva54/simpleusercontrol/blob/master/src/main/java/com/siva/UserManagementApplication.java
From what I have read, An application should contain any of the configurations from the following URL to declare how the applications manages the context,
http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/using-boot-using-springbootapplication-annotation.html
I haven't used any of those contexts, However my application works fine and I'm able to run it without any issues. Am I missing something here? Can you please help with the info of how my application is able to start and manage the context/dependencies automatically?
Thanks in advance
#SpringBootApplication is equivalent of #Configuration, #EnableAutoConfiguration and #ComponentScan. Let's consider why your application works without of any of this three annotations.
Why it works without #Configuration:
When Spring will scan packages, it will find all classes marked by #Configuration and will use them as part of configuration. But in next line you manually passed UserManagementApplication as configuration source:
SpringApplication.run(UserManagementApplication.class, args);
So spring doesn't need to find this class by scan. Therefor it is not necessary to mark it by #Configuration.
Why it works without #ComponentScan:
Class UserManagementApplication has #ImportResource("classpath:spring/application-context.xml") annotation. That means file spring/application-context.xml will be included into configuration. And this file contains next line:
<context:component-scan base-package="com.siva.*" />
So, you don't need use annotation for scan packages, because you already declared it in the xml file.
Why it works without #EnableAutoConfiguration:
This annotation allows to Spring to try guess and configure the components automatically. For example, if you include the following dependency in your build.gradle:
dependencies {
compile 'org.springframework.boot:spring-boot-starter-data-mongodb'
}
Spring configures all the components required to work with MongoDB automatically. And all you need just specify host and user/pass in the aplication.proprties file.
But you preferred to declare all needed beans manually in the spring/application-context.xml file. So, you simply don't need #EnableAutoConfiguration annotation at all.

Resources