I want to build an MVC app using Spring (first timer here).
As such I want to embed Jetty as the servlet engine. Jetty however doesn't stricly follow the java beans pattern, so I can't launch some classes from Spring (they use overloaded setters or non setter init methods like addXYZ).
What is the accepted/recommended practice for structuring this project? Obviously all my code fits nicely in the MVC model, but for Jetty:
Do I encapsulate all of Jetty (or any
other non-bean friendly component) in
my own Spring-friendly bean?
Do I try to instantiate as much of it as
possible in spring and just extend
classes that aren't bean con-formant
to make them act like proper beans?
Is there
another option?
Generally speaking, I'm for the 2nd point - i.e. try to use spring utilities like factory-method, init-method, <constructor-arg> and things like that to overcome the fact that something is not entirely spring-friendly. It is rarely the case that it's impossible to configure beans with spring. And for the cases when it is impossible, create wrappers
You can also instantiate the 3rd party beans programatically:
via a FactoryBean
via JavaConfig
Related
I am refactoring an application using Spring by moving some shared components (a webservice client) into a library. The components cannot work on their own so still need some beans from the application that uses the library. What is the best practice for this?
I have created a #Configuration class so the application only needs to #Import it to use the library, but the application also needs to supply a Jackson ObjectMapper and a Settings object containing how to contact the webservice. I autowire the ObjectMapper and Settings beans into various beans used in the library. The application uses the library by injecting the Client into its code and calling it.
This works, but I'm not sure it's the right style. In IntelliJ IDEA as I develop the library, it complains that the beans the library injects don't exist with a red underline, which is true, they don't exist. But normally when I see red all over files that cannot be resolved, that tells me maybe I'm not doing it the right way.
The library needs to be used with applications using Spring 3 and 5. What is the proper way for a library to ask for things like ObjectMapper when it's not appropriate to define its own (because the app will already have Jackson), and "proprietary" beans like the Settings object?
Your question is a bit broad but hopefully I can give you a hint to the right direction.
The components cannot work on their own so still need some beans from the application that uses the library. What is the best practice for this?
First: This components should use an interface instead of some concrete beans.
Second: If you have a reusable library then this typical needs some configuration, that can not been part of the library itself because it depends on application that use that library
Third: because of second (and first): your library should not been based on any form of auto wiring, instead your library should been based on explicit (or default) configuration.
And this solve the problem. Use interfaces and an explicit configuration of your library in your application. As well as add an good documentation of the needed configuration to your lib.
Using inspiration from #Kayaman and #Ralph, I decided it's not appropriate to expose Spring as a part of a library to be used directly from the application's context. I realize now it's also not appropriate because the library could define duplicate "private" beans it did not want to expose. I was overthinking it. If I wanted to use Spring, I found out I could do this:
public class Factory {
public static Client createClient(ObjectMapper mapper, Settings settings) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("mapper", mapper);
beanFactory.registerSingleton("settings", settings);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(beanFactory);
ctx.registerBean(ClientConfiguration.class);
ctx.refresh();
return ctx.getBean(Client.class);
}
}
Essentially, it's OK to use Spring as an implementation detail. Since the configuration I made exposed only one bean, it makes sense as a factory method. In the application I would create a method like this:
#Bean public Client makeClient(ObjectMapper mapper, Settings settings) {
return Factory.createClient(mapper, settings);
}
Of course the Bean method would have ObjectMapper and Settings injected in from the application's context, or could be inline constructors for ObjectMapper/Settings.
Instead, what I decided was since the client had few enough beans and none were lazy, I just removed Spring annotations entirely and just built the object graph by hand in almost as much code as the spring context took. Now the library has the benefit of not requiring Spring at all at runtime, in a supposed non-Spring application.
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.
I have several CDI bean controllers, that I would like to reuse within my desktop web applications, and mobile web applications (herein called web-components).
Scenario:
I have one Java EE application (EAR)
I have a web.war component (to refer to the desktop web application)
I have a mobile.war component (to refer to the mobile web application)
I dont want to use responsive design on the main web application because of how it was designed, so I simply need to develop a mobile version, to be accessed at a different subdomain
m.mydomain.com
My intention is to create reusable-component.jar to contain all the CDI controllers, and then include this JAR to the web components.
However, this fails Jboss weld detects the same name for the bean, weld error 00414
However, I have defined some generic request processing lifecycle on this CDI beans e.g.
#OnRequest()
#Named
#RequestScope
public class MyBeanController{
}
The #OnRequest is a lifecycle callback I have defined, which does a lot of things, including permissions to certain resources which are defined externally in a configuration file.
What I have thought about.
Remove the #Named and scope annotations in the reusable-component.jar, and then extend them separately on the different web-components.
Problem, I have several cdi beans, quite a lot because this is a huge applications, and extending each of them in the web-component will be a lot of refactoring.
My question:
How can I manage to reuse this CDI beans, in this web-components?
FYI: I have looked at the alternative/stereotype, specialization scenarios, this will still require me to extends all the beans anyway, and my #OnRequest annotation lifecycle processing does a bean lookup using the #Named or bean name (as specified in cdi), so if I were to use specialization or alternatives, how will this lookup be affected?
What I recommend to most people in this scenario is to define two separate WARs and a common JAR. Include that common JAR within both WARs (as WEB-INF/lib entry). While the JAR is duplicated, the code is not duplicated.
I've seen at least three ways of acquiring dependencies in a Java object without coupling the object to the creation of the dependency;
Dependency Injection
- some framework injects a required object into another object based on an external configuration, example: Spring managed beans
Dependency Lookup
- a class looks up a required dependency in some kind of directory service, example: JNDI lookups in a Java EE container
Static Factories
- an object in a global scope provides instances on demand - the standard Java SE APIs seem to be littered with these, example: java.util.Logger.getLogger(name), java.util.Calendar.getInstance()
What guidance can you provide as to which is most appropriate for a situation?
I prefer dependency injection, because the object need not know how it acquires the references it needs.
Dependency lookup still requires the object to know about the lookup service and its URL.
Static factories are similar to lookup services.
I prefer dependency injection.
When I talk about DI with Spring Framework I see following
It's supported by IDEs (error check, visualization).
You can setup other needed stuff like AOP, properties loading, ...
You have big config possibilities - XML, annotation, JavaConfig
Can be use also in desktop application.
These outbalance every negatives like dependency on another library. Why should I use another approach?
This really depends on the context. If you are writing a self-contained Maths API you might want to use static factories because the code will be less verbose, setup-free and maybe more efficient. If you need to access/provide a remote dependency, a JNDI/LDAP lookup, or ESB messaging would work well. For injecting your services/DAO's/datasources into your typical enterprise server code you'd be better off using one of the common D.I. frameworks like Google Guice or Spring.
There is no single 'best' solution in software design; it's always a tradeoff.
I'm writing a java library that will be used by an existing application. I'm using dependency injection so testing is easier, and I'm familiar with Spring so I was planning to use it to manage the dependency injection while testing. The applications that will eventually use the library are not Spring-based, however, nor does it use any IoC/DI container of any sort currently. My question is, what's the best approach for injecting dependencies if Spring or Guice are not used? Should I consider something like a factory method to instantiate and wire the objects? The dependencies are all inside the library, so it doesn't seem appropriate to have the application instantiate each dependency to create the main object.
what's the best approach for injecting dependencies if Spring or Guice are not used?
If your library was written in a DI-friendly idiom. It should be fairly easy to use as a straitforward java API. Think of your past experience with spring. There are several libraries out there that fit perfectly with the spring model but were written before spring time. I don't see nothing bad with a new followed by a couple of setXX followed by a call to the real work method. Just be extra careful, since, among other things, your client can forget to call thouse init methods that spring reliably calls.
Should I consider something like a factory method to instantiate and wire the objects? The dependencies are all inside the library, so it doesn't seem appropriate to have the application instantiate each dependency to create the main object.
Let the client application decide that. You are providing a library. Let the API client wire its own objects. Provide an example. Later, that same example can be used to make the factory method on the client's domain. Maybe the client application has it's own way to configure itself, and it would be desirable if the API your library provides to be flexible enough to take advantage of that.
Or maybe you can include guice. The licence is Apache. Just like a whole piece of Java itself.