Custom database-driven CDI Context - java

I'd like to extend usage of CDI in the app I develop. What I need is something like application context/scope but I need to handle multiple instances of beans based on how many records are in the database/configuration.
To be more specific, in our database, there's a table called PODs and for each record in this table, I need a separate group of beans (services, repositories, etc. - a whole object graph). There's no need for dynamic behaviour - it's OK to restart application when a record is created/deleted in this PODs table. But ideally items defined within this PodContext for a specific POD should be able to inject beans within the context of the same PodContext.
The obvious problem here is how to specify for which POD a bean instance should be created/injected.
That leads me to a question if a custom CDI context is actually suited for such a use case but without losing all the CDI goodies and building all the object graphs manually, I don't see a good way out :(
Update: My colleague suggested a solution for Spring Framework - we could have a parent context with all the shared application-wide beans, and also one child context for each POD, which would define beans for that specific POD. It's possible because Spring allows such context hierarchies. Is there anything similar in CDI?

Related

How are IoC and DI used in Spring MVC

I’m taking this udemy course all about Spring Hibernate etc. The course started with explaining how Injection of Control and dependency injection works not in a web perspective just like having simple classes or beans, defining beans and their dependencies inside a config xml file or inside the actual class Using java annotation and then a main class where the beans are created. I understood that despite not really seeing the big benefit of using IoC and DI other than separating roles like creating and maintaining objects and adding dependencies the object needs and I guess when the project is bigger this makes it cleaner and easier to follow right?
However what I don’t understand is how IOC and DI ties in a full spring MVC project. Like I understand using the #Controller annotation means it’s like an #Component and you could make it scan the components automatically when it creates beans but like unlike before there isn’t a main class where beans are created and configured rather I have a controller class where I manually create objects and models and pass that back to the views where I can use the values in the model. I don’t see how I use IoC or DI here? Or is it because it’s a simple project and perhaps the objects we created didn’t have many dependencies?Or are a lot of the uses and implementation done internally or automatically?
I am just struggling to a) see why IoC and DI are that important and b) how are they actually used in a Spring MVC project where you don’t have a main class where you do create beans.
A) Create a project, but don't add any dependency (or web-mvc). Then do it yourself then see how much need time to create configure manually. If it is just a simple mvc project, you can do it manually, but if your project increase day by day then a huge configuration file to maintain your project properly. But when you are professional developer, you don't have so much time to configure all those manually. So here is come the solution IoC and DI. Controller or other anotation are configured in build-in jars. You don't have to worried about to create controller or to create bean, just use them when you neer them. It's save your time as well as headache about is it working or not. It's increase your productivity while your are working on a big project.
B) Yes, there is no main class in web project. To run a web project, you need a server. The server first looking for a configuration (In spring, it's web.xml, dispatcher-servlet). If it available then expand the configuration file, if not then throw an error. In that configuration file, explain everything about the web project. What should do, what is not mandatory, what is entry point etc.
So, IoC and DI are very important because to understand how a web project work behind the scene or how all component work together.
IoC is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application.
The advantages of this architecture are:
decoupling the execution of a task from its implementation
making it easier to switch between different implementations
greater modularity of a program
greater ease in testing a program by isolating a component or mocking its dependencies and allowing components to communicate through contracts
Inversion of Control can be achieved through various mechanisms such as: Strategy design pattern, Service Locator pattern, Factory pattern, and Dependency Injection (DI).
You can go with Annotation based configuration, where you can define #Configuration class and return the required beans using #Bean annotation.
Also you can use #Component to your POJO class to treat it as Spring bean.

How to reuse classes in a Spring Boot REST application?

I have a Spring Boot REST application with JPA entities and Repository classes (and related services) that works very well. Now I would like to reuse these classes for other purposes, like weekly CRON jobs and similar one-time processes which will be run from the command line.
What would be the best way to do this? The challenge is that the persistence context properties are set in application.properties, and the persistence context isn't initialized unless the Application class is initialized.
I can break out all of these classes into a separate project, and use a different way to define the persistence context there, but this becomes more of a maintenance headache if anything changes with the entities or DAO methods.
What I would really like is to have a way, from the command line, to tell Spring Boot to run another class instead of the main Application (and have the persistence context properly initialized). Any way to do this?
(Note I asked a similar question which got no response: Possible to use Spring Boot repositories from another main class?)
[Edit] is it possible to do this by creating a #component that implements the CommandLineRunner? I just want it to run a simple one-time process and not the full REST application.
There are a number of ways you could do this.
You can have multiple Main classes, and then select which application yuo want to start select main class, however if you don't know how ComponetScan works you will end up loading both applications if you are not careful.
Another way is to use Profiles, you can set the profile when you start your spring app, and then have your web profile that will start Tomcat, and a command line profile that will not .
In the project I'm working on we have choosen to have the data-layer as a completly separate module (same gradle project), which has it's own Spring Context. The data-layer spring context is then used as the parent context for other applications, as a reusable component. It is a somewhat cleaner separations of concerns, were the shared code is clearly marked, instead of having multiple applications inside the same code mudule.

Have one Tomcat application get a bean from another one

Currently I have a Spring project that uses Spring JPA to work with data objects and my database. All of it's functionality can be accessed by calling a single facade bean. I want to make a web application based on this data model, but I don't want to extend this project any further. Instead I would like to separate my persistence and service layers from an actual web application layer. That said, I want to package this project into a ".war" file and deploy it on my Tomcat instance. Upon demand from any other application working on Tomcat I would like to have this other application to be injected with the facade bean from my ".war".
I'm sort of new to Tomcat, and googling doesn't really help me much. So here are problems and questions that I have with this concept:
Is this the right way to do what I want? What I mean is I want behavior provided by my current Spring application to be accessible and reusable by different web applications working on one server. This might be a common case and I would like to know if this is ok as a solution.
If I have this facade bean in XML context or in annotation context of my project, how can I make this bean visible to any other application working on the same Tomcat instance upon being deployed? What should I write in my web applications to have them wired with this bean? If I want this bean to be a singleton and have all calls to it's functionality synchronized, should I do this through my code/context, or can I have Tomcat somehow take care of this for me?
Thanks in advance.
You might want to consider a REST API approach. You can't do "cross application injection" with Spring and JNDI can be cumbersome to use.
Webapps (the things that run in a servlet container like tomcat) are isolated from each other, by design. Sharing may well be a bad idea. However, to share, you can use JNDI. Setting up JNDI in tomcat 7 is described here. You will need a custom resource factory.

Spring ListableBeanFactory performance

I'm using ListableBeanFactory to fetch beans that match specific annotations. While this works, the performance is low. Also, I also know the set of classes which will contain the annotations. It seems the ListableBeanFactory is searching all the beans. How do I tell it to search only a small subset of classes so that I can improve the performance?
Generally speaking this spring feature does not perform well in the real-time repeating tasks. Try to fetch these annotated beans during the startup and then access them. Or just don't use Spring for this particular case. Another way is to use child context instead of main Spring context: you can create additional child context containing beans from the specific package or just the specific beans, they will still be able to resolve their dependencies from parent context but not vice versa.

java web applicaton layout, please explain some design principles/patterns

I'm looking at this java web application that is using hibernate, jsp's, and spring framework. (from what I can tell!)
the file layout is like this:
classes/com/example/project1
inside project1
/dao
_entity_Dao.java
/dao/hibernate/
_entity_DaoHibernate.java
/factory
DaoFactory.java
DaoFactoryImpl.java
/managers
_entity_Manager.java
/managers/impl
_entity_ManagerImpl.java
/model
_entity_.java
/service
_xxxx_Service.java
/service/impl/
_xxxx_ServiceImpl.java
Have you guys read about this sort of layout somewhere? Is it considered best-practice?
What is the difference between a Factory and a Manager and a Service? (high level)
For typical layout of an application built with Spring I'd look at the example web applications that ship with it (meaning Spring).
Using things like DaoFactory is definitely not be a best-practice, the Daos should get injected instead. In general you should not need factories with Spring except for some unusual cases. Injecting is done when the web application starts up, spring reads the configuration information and constructs all the objects and plugs them in according to configuration xml and/or annotations (this is assuming singleton-scope for your objects, which is usual for stateless things like daos and services, things scoped as prototypes get new copies created as the application asks for them).
In Spring applications a service is similar to a Stateless Session Bean, it is a transactional layer encompassing application logic for a use case. So if your user takes an action that has the effect of causing several different tables to get updated you can inject the daos into that service, have a method on that service do the updates on the daos, and configure Spring to wrap that service in a proxy that makes that method transactional.
I've seen manager used as another name for what I described as service. Here I don't know what they're doing with it.
I don't like the idea of combining your interfaces and impls in one project. Just because you want to consume the interface doesn't mean you want to consume the impl and it's cumbersome transitive dependencies. The main reason is because there will be more than one impl (hypothetically, i.e. JPA/JDBC/Hibernate, or Axis2/CXF, etc.). The interfaces should not be bound to the implementation, otherwise the point is lost. This also allows for easy dependency injection as the impls simply reside on the classpath, then something like a Proxy or Spring (e.g.) can inject the implementations.
In all likelihood, all you need is a:
Interface Project
dao
EntityDao
types
Entity
HibernateImpl Project
dao
EntityHibernateDao
src/main/resources/
EntityMapping.cfg.xml

Categories

Resources