Bean and Dependency Injection configuration from Database Instead XML - java

Currently we have all service class configuration defined in Application-Context.xml file. Application context will be initialized during the application startup with all beans defined in the context file and spring handles dependency injection.
I am looking for a solution where it has to load particular service class during run time based on specific parameter from Database.
For example, there are two classes exist in code base such as FooService1.java and FooService2.java. Each class will have dependency with appropriate DAO class such as FooDAO1.java and FooDAO2.java.
Instead of defining these in applciation-context.xml file, a run time parameter will decide which service needs to be loaded and its corresponding DAO which needs to be injected. Basically what i am trying to achieve here is DB oriented Dependency Injection to keep all application context information in database instead of XML.
Tables would look like: SERVICE_BEANS, DAO_BEANS and some intermediate table to have dependency information.
I just saw JdbcBeanDefinitionReader class in spring. Can I use this to implement DB oriented DI? I don't see much example on this. Please let me know if anyone has any examples.

I think you can generate beans # runtime and register them to spring-context.
Refer to Registering beans(prototype) at runtime in Spring
Hope that helps !

Related

Use Spring properties loading without initializing the Spring context

I love the Spring properties loading mechanism. The fact that you can define several profiles and override or extend properties with other profiles, that you can use different file types (.properties, XML, JSON, ...) to store your properties, that you can use the value of other properties to resolve its own value, aso.
But to use the properties, you have to somehow initialize the Spring context (#SpringBootApplication or #SpringBootTest). And I would like to use this property loading mechanism in some libraries, where I cannot guarantee that the context is loaded (and I do not want to load it).
So, my question:
Can I somehow create a class that uses the Spring libraries to load the properties (on demand) in the same way Spring loads its properties?
Other classes will then use this class to access the properties. No need to load with annotations.
I was searching for this for some time, but I haven't found a solution, yet.
Would be great if so. knows a solution for that.
Regards, stay healthy and merry X-Mas!
The property lookup mechanism is defined by interface PropertyResolver, extended by interface Environment to support profiles, further extended by interface ConfigurableEnvironment to support PropertySources, i.e. the concept of searching through a set of property sources to find a property.
It is implemented e.g. by class StandardEnvironment, which defines property source for:
system properties
system environment variables
All the above are part of package org.springframework.core.env, i.e. part of the spring-core-XXX.jar file.
Support for application.properties files is added by class ConfigFileApplicationListener in package org.springframework.boot.context.config.
The class needs an instance of SpringApplication in package org.springframework.boot.
They are part of the spring-boot-XXX.jar file.
So, getting basic Spring property support is easy, just create a StandardEnvironment object.
Getting application.properties files loaded is deeply embedded in the Spring Boot code, and would be really difficult to do without initializing the Spring context.

Do action before spring context created

How can I execute the action, before Spring context created? I found only one solution that more or less can satisfy me, it is listening ApplicationStartingEvent but I don't know how correctly do it because Spring doesn't see listener bean because context not created yet. So maybe someone knows ways how to catch ApplicationStartingEvent or maybe another better solution to do it.
Interface ApplicationContextInitializer could suffice for your requirement.
Read ApplicationContextInitializer documentation
Implementing ApplicationContextInitializer allows you to do additional tasks/initializations before persistent bean definition is loaded (i.e. your application-context.xml). One such use is, when you want to select profiles before you will load definitions.

Spring - dependency injection - testing with different implementation

One of the main advantage of using spring dependency injection is for testing the functionality using same interface with different implementation without making any changes in the code, that is through injecting these different implementations(dependencies) in configuration file.
Lets take an example where we have developed our application with java configuration/annotation based (No .xml files at all).
We have done a code freeze and have deployed the code in server.
Now for a QA team to perform testing they need to inject different implementations for the interface by making changes in configuration file without touching code.
If its a .xml file, devOps team can inject the different implementation by injecting that bean name and can restart the server.
But since we have used the annotations based/java based configuration, How can we achieve this ?
Thanks in advance.
One of the main advantage of using spring dependency injection is for
testing the functionality using same interface with different
implementation
One of main advantages of Spring is indeed the dependency injection facility.
But you will also find very often cases where you have beans with a single implementation :
beans that rely on an interface but there is only one implementation for it.
bean that don't rely on any interface but are straight classes that you want to turn into injectable beans.
We have done a code freeze and have deployed the code in server. Now
for a QA team to perform testing they need to inject different
implementations for the interface by making changes in configuration
file without touching code.
Spring and more generally dependency injection pattern/frameworks are not designed to perform hot swapping or implementation modification of a deployed component without repackaging the component.
At startup, Spring creates its context and loads all required beans for the application in its container.
If you want to change configurations of some beans, the most clean and side effect less way is destroying the spring context/container, repackage the application with the needed changes and restart it.
If its a .xml file, QA team can inject the different implementation by
injecting that bean name and can restart the server.
Ideally, the QA team should test the implementation that you deploy in QA env and that will be used by final users to stay the closest of the real functioning of the application.
Now, if because of some specific constraints, some components to test by the QA should be mocked/stubbed in a some way, just create a different build for that.
Spring Boot Profile and Maven Profile features can help for.

Java based dependency injection in Spring

I'm working in a webapp and this is the first time that I'm using Java based configuration. I have a bunch of class to configure all:
ApplicationContext
PersistenceContext
SecurityContext
WebAppInitializer
WebMvcContext
Now I'm defining Spring Data repositories and the service layer so I need to inject the repositories there. Normally I would use Autowired but I've read that it is preferable to define the injections manually so the question is, where?
Maybe neither of the previous configuration classes is suitable for such task but, do I have to create a single class to define all the injections or is better to have on for each function? What happens if the project grows too much?
I think that the main question would be what is best way to organize dependencies in a Spring project. What do you do?
I add here an image of the structure of the project as a petition. I'm trying to decouple layers and now I need to inject UserRepository to UserService.
No, I would not define a single class to do all the injections. All your classes are coupled that way.
I don't understand what "define the injections manually" means. You have to specify them in either XML or annotations. There's no other way that I know of.
You don't say if you're using XML or annotation configuration. I find myself using the latter more of the time, with only enough XML configuration to tell the Spring app context to scan for annotations.
The Spring idiom would have you specify your configuration in layers if you're using XML. It's a moot point for annotations, because they go into your source code.
Your application will read the Spring context on start up, instantiate all the beans, and wire together the necessary dependencies. You're good to go from then on.
I disagree with the link you provided. Avoid autowiring? No.
The article said that he recommends using XML configuration for large projects. This is a very small project at this point. It seems to me that auto wiring with annotations would be fine even by the article's author's words.

How should each class in an application retrieve the Spring application context?

How should each class in an application retrieve the Spring application context? Or, stated another way, how many times should an application invoke new ClassPathXmlApplicationContext("applicationContext.xml")?
Usually a class does not need the application context, but it needs some of the objects Spring injects. And this is configured in that applicationContext.
As such an application typically calls new ClassPathXmlApplicationContext("applicationContext.xml") only once.
With dependency injection, you shouldn't have to, in general. But if your class really needs to be aware of the application context, implement the ApplicationContextAware interface. Spring will automatically call the setApplicationContext method defined in that interface to provide your class with the application context.
Note that if you're trying to gain access to filesystem resources, you should use ResourceLoaderAware. If you want access to the message source, then don't implement an interface; instead, inject a reference to the MessageSource bean.
I think you should take the advice from the answer to your other question here. Implementing ApplicationContextAware or ServletContextAware (if you are in a servlet container) is the best way to get the context.
Look up how spring handles Dependency Injection or Inversion of Control.
Once.
Actually you should let Spring do the heavy lifting and build/configure the classes rather than the other way around.
The whole idea is that all classes can be built without having to call the outside world for dependencies, which are 'magically' provided by the Spring framework.
This approach was invented to get away from the ServiceLocator pattern to which you are alluding, i.e. get a reference to an object to get the dependencies you need, ala JNDI.

Categories

Resources