Registering Spring beans without Component Scanning - spring

I have MySimpleController and I need to extract this controller to a common library.
package xxx.mypackage;
#Controller
class MySimpleController{}
This library has a different package name, yyy.newpackage which is different than previous xxx.mypackage. Because of this, It is not suitable for component scanning.
Here is the question: Is there a way to register this controller without component scanning? I just want to include my jar and expecting my controller properly. I have seen some definitions in META-INF folder but could not be sure that this is the correct way.

Create configuration for whole 3rd party library
#Configuration
public class CustomConfig {
#Bean
public MySimpleController mySimpleController(){
return new MySimpleController();
}
}
and import this configuration without scanning
#Import(CustomConfig.class)
My sample is in JavaConfig, but this apply to xml configuration too.

add this controller as a bean with the new package in your applicationCOntext. By doing so, it would be the only bean loaded through the xml config whereas everything else is through your component scan.
<beans>
<bean name="myBean" class="yy.MySimpleController"/>
</beans>

Related

How to override #RestController bean in springboot

I have a #RestController annotated class defined in a 3rd party .jar file in my springboot app. It's initialized via package scan. How can I overwrite this 3rd party controller bean with my own controller bean? Is there something like the "alias" of the xml configuration in spring-boot with java configure only environment?
Each mapping must be unique.There is no way to overrule an existing #RequestMapping.
There are workarounds for this though.
you can refer this post to get an idea about the answer :
How to override #RequestMapping in another controller?

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 Boot Bean 'Required bean of type that could not be found'

I have been working on learning how to use spring data and I have created a very simple project to test it. The folder structure and applicationcontext.xml is shown here:applicationcontext.xml and folder structure
The error I am getting is shown here:console error output
.
I have the applicationContext on my classpath and have a bean of that class declared, any idea as to what my problem could be ? Thank you.
EDIT:
I have updated my post to show the main class and the dao class, as well as my pom.xml contents (as at this point, I am wondering if I need to include another dependency . . . )
main class
dao (repository)
I miss the following line in your application log:
... o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [applicationContext.xml]
So I assume your applicationContext.xml file is not loaded at all.
Either add
#ImportResource("classpath:applicationContext.xml")
to your application class or add the
#Repository
annotation to your UserRepository class.
In my opinion you should avoid mixing Java and XML Spring configuration if possible.

Delay spring xml imports

I have an application where I have to read all application properties from properties files. Then override them from a external cache framework. Then initialize spring beans.
I am using Java Config of spring to read properties and override them. And using #import to load xml files. But xml files import as soon as context starts loading, resulting all the xml beans being initialized.
So is there a way I can delay xml files import until I load all the properties first?
You can use the following code.
<beans default-lazy-init="true">
<!-- no beans will be pre-instantiated... -->
</beans>
or individually add lazy-init on beans which you don't want to load.
Or
There are lot of ways you can achieve your requirement One of which can be use of depends-on or #DependsOn if you are looking for annotation based configuration,
You can read property file after that you can create a cache bean and use
depends-on to let the container know you bean is depending on some other bean you can initialise a cache bean and use the same as you see fit.
See this example for better clearity.
<bean id="primaryBean" depends-on="cacheBean"></bean>
Now IoC guarantees that depending bean will be created before the bean which depends on this bean, So you will have an instance of this bean, and can use it.
Other than this you can implement LifeCycle interface
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
For more references you can refer spring docs.

How to use Spring on a class situated in a library?

Although I'm comfortable with other DI especially MacWire, I need for a project to deal with Spring.
I'm trying to integrate an external library of service that I am developing to a main application that uses Spring to instantiate its services. I'm wondering how can I do such that the code in the Library is treated the same as the code in the source with respect to Spring?
That is instantiating class in my library, from with within the main source of the project using Spring. Do I just give the path of the package to scan the bean from?
Spring configuration file help you to achieve DI. What I understand from question is, you are looking for a way to use Spring capabilities to instantiate a class. The way to instantiate bean remain same for external service or your own library code.
Say if you have classes like:
//External Library class
package com.test;
public class HelloWorld{
...
}
// Your class
package com.abc;
import com.test.HelloWorld;
public class MyClass{
HelloWorld obj;
...
}
Spring XML configuration file will look like,
<beans>
<!-- External library class -->
<bean id="helloWorld" class="com.test.HelloWorld" />
<!-- Your class -->
<bean id="myClass" class="com.abc.MyClass">
<property name="obj" ref="helloWorld"/>
</bean>
</beans>
I recommend you to refer 'Spring Dependency Injection' in Spring documentation..

Resources