Where should I put the logic of my app when i'm using JSF framework? As I understand managed beans are used only for getting/setting the properties of the form and also have controllers methods. I don't think that implementing the logic in controllers method is a good way. Of course I can use ejb to implement the logic and inject it to managed beans, but how it will work on servers that don't have an ejb container(e.g. Tomcat).
I don't think that implementing the logic in controllers method is a good way.
Indeed. Use business services like EJBs.
Of course I can use ejb to implement the logic and inject it to managed beans, but how it will work on servers that don't have an ejb container(e.g. Tomcat).
You could use OpenEJB to enrich it with (limited) EJB 3.x capabilities. An alternative is Spring, that's what they used during the EJB 2.x era when EJBs were hated.
Related
My question is not only if action classes can be scoped to singleton, but I also want to know which are the best practices. Both in context of Struts2 and Spring. Best scope of VIEW (say request or session), for controller and model.
Struts2 Actions are managed by the Struts Container. They are ThreadLocal, hence every request has its own thread-safe copy of the Action.
If you use Spring to handle them through the Struts2-Spring-plugin, there are multiple levels of usage:
you can let the Struts container instantiate them, and handle them through Spring for the Dependency Injection, or
you can let Spring take over control and be fully responsible for the whole lifecycle of every Action. In this second case:
if you declare an action as a bean in a Spring XML configuration file, the action will get the default Spring scope, that is Singleton (scope="singleton"). THIS IS DANGEROUS, USELESS, and 99.99% of the times NOT WHAT YOU WANT, because you will lose a fundamental part of the framework capability, actions will be turned into kind-of servlets, thread-UNsafe, and many problems will arise;
to prevent that, you can put the scope="prototype" in the bean declaration, that will let Spring instantiate the action without affecting its nature.
If you are inside a container Java EE 6+ compliant (for example, Jboss 7, Wildfly 8, TomEE 1.7, Glassfish 3+, ecc...), the Contexts and the Dependency Injections are handled through CDI. If you want, you can use the Struts2-CDI-plugin to allow CDI to handle your actions and inject dependencies through the #Inject annotation (instead of the #Autowired one)
I've used Spring a lot in the past, then after discovering CDI and the CDI plugin, I've switched and never looked back, so I vote for the n.3
I have read through the SimpleInjector documentation a few times. But have a few questions.
Context:
3 tier app (presentation (mvc + api controllers), service (business logic), data (repositories, entities, etc)
Unit of Work is a thin wrapper around EF's DbContext
my DbContext and Unit of Work are registered PerWebRequest, using
RegisterWebApiRequest causes an exception, because the Unit of Work is used
outside of Web API requests.
my MVC and Api controllers registered using RegisterWebApiControllers(GlobalConfiguration.Configuration) and RegisterMvcControllers(Assembly.GetExecutingAssembly())
Each controller has one or more services injected into it.
Each service has one or more repositories injected into it.
A service may also have another service injected into it.
I want the same Unit Of Work/DbContext to exist in all my services/repositories.
Questions:
Because I am using services in my MVC controllers as well as API controllers; does that mean I can not use RegisterWebApiRequest in place of RegisterPerWebRequest?
none of my services, repositories, etc, maintain any state, I would get the same functionality using PerWebRequest as Transient; is there any advantage to using PerWebRequest over Transient?
Please read the following q/a: How to configure simple injector container and lifestylse in a MVC web app with WebAPI, WCF, SignalR and Background Tasks. The answer explains that:
Putting your Web API in the same project as your MVC controllers is a bad idea from an architectural perspective.
But if you want to do this, you can use the WebRequestLifestyle in both type of applications. The WebApiRequestLifestyle is meant as lifestyle that works for Web API for both IIS and self-hosted environments, but since you placed the Web API controllers in the same project, you are clearly only interested in IIS-hosted; in that case the WebRequestLifestyle will do just fine.
Because I am using services in my MVC controllers as well as API controllers; does that mean I can not use RegisterWebApiRequest in place of RegisterPerWebRequest?
Both lifestyles use a different way of caching. The WebRequestLifestyle uses the HttpContext.Current.Items dictionary to store its SimpleInjector.Scope instance, while the WebApiRequestLifestyle uses the CallContext class to store the Scope during the lifetime of a single asynchronous operation.
Just as the WebRequestLifestyle can be used while resolving Web API controllers, you can use the WebApiRequestLifestyle (or the underlying ExecutionContextScopeLifestyle) for MVC controllers as well. But if you want this, you will create your own IDependencyResolver implementation for MVC that will explicitly start and end an ExecutionContextScope. The absense of a Scope stored in the CallContext is the reason resolving MVC controllers fails when registering services using the WebApiRequestLifestyle. But while it's possible to use the WebApiRequestLifestyle in MVC, the otherway around is much easier, since no custom code is required.
none of my services, repositories, etc, maintain any state, I would get the same functionality using PerWebRequest as Transient; is there any advantage to using PerWebRequest over Transient?
If services don't have state, it doesn't matter what lifestyle they have. The only restriction is that they have dependencies that have a lifestyle that is equal to or longer than their own. Violating this restriction is called Captive Dependencies and can cause all kinds of trouble. Because captive dependencies are bad, Simple Injector v3 checks and prevents this for you.
Although you can probably make all objects in your configuration scoped (non-transient), making them transient is usually easier to configure, and might result in better performance (although you will probably never notice the difference in real life).
I'm replacing the service tier in an existing older Struts2 project with Spring service beans developed for another project.
I'd like to just #Inject these service beans into my Action classes.
Is it required to use Struts' Spring Plugin? Or can I add Spring into my Struts web application like I would any other (ContextLoaderListener, applicationContext.xml, context:component-scan)?
Am I missing some reason why the Struts Spring plugin helps me in another way?
Many thanks!
Well you can do the most of the things what you have described in your question as Services layer is completely out of view for the S2 and Struts2 do not care how you are creating your Service layer instances and other things.
Benefits i am seeing of using Struts2-Spring plugin is to delegate creation of Struts2 related things to Spring like Action classes creation,Interceptors,Results etc.
My Suggestion is to use the plugin as you are going to use the Spring in your application so its very good and flexible as well powerful to use the power of Spring DI to create required objects needed by S2 else S2 will use its own data creation factory to create framework component.
Why wouldn't you use the Spring plugin?
It's essentially invisible, uses Spring to create your actions (including injecting other Spring beans), etc.
Guice's #Inject doesn't know anything about Spring beans, AFAIK, so you'd be naming classes manually, they'd be instantiated via normal Java/Guice mechanisms, wouldn't be injected with their own Spring dependencies (unless you did it manually, or via AOP, or whatever).
You'd also need to use non-Spring mechanisms for doing injection in testing, which is fine, but unless you provide more details regarding your usecase, I don't really see a reason to bypass the functionality the Spring plugin provides out-of-the-box.
I'm using SignalR in the application I am writing, but I'm confused by examples like the last example at https://github.com/SignalR/SignalR/wiki/Hubs in particular the use of AspNetHost.DependencyResolver
IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<MyHub>();
If I'm not mistaken this is a Dependency Injection tool? Problem is I'm using StructureMap for everything else, and I'd rather not have two dependency Injection frameworks.
Is AspNetHost.DependencyResolver necessary?
SignalR has a bunch of dependencies/services that it needs to function, and it gets those through a DependencyResolver.
You can replace that resolver with your own (e.g StructureMap, Ninject etc.), but if you don't, SignalR will use it's default resolver.
I'm working on a large legacy application using stateless session beans that has recently been migrated from EJB2 to EJB3, and I'd like to use dependency injection. Unfortunately, in a (IMO misguided) attempt to achieve decoupling, all actual business logic lies in "manager" classes to which the session beans forward their calls. Those manager classes then often use other EJBs.
Can I somehow make these manager classes capable of being injected into the EJBs via #Resource and then having the other EJBs injected into them via #EJB?
The application has to run on glassfish 2.1.
(...) all actual business logic lies in "manager" classes to which the session beans forward their calls.
That was a very common pattern with EJB 2.x allowing to unit test the "manager" classes easily, outside the container, without any adherence to the EJB API.
Can I somehow make these manager classes capable of being injected into the EJBs via #Resource and then having the other EJBs injected into them via #EJB?
Not out-of-the-box with Java EE 5. Injection is limited only to first class constructs defined in the Java EE platform, including:
SessionContext object
DataSources object
UserTransaction
EntityManager interface
TimerService interface
Other enterprise beans
Web services
Message queues and topics
Connection factories for resource adaptes
Environment entries limited to String, Character, Byte, Short, Integer, Long, Boolean, Double, and Float.
In Java EE 6, this would be possible using CDI (JSR-199) and the #Inject annotation in EJBs to inject your managers and also in you managers to get EJBs injected.
Maybe you could try to deploy Weld (the RI of JSR-199) as part of your application on GlassFish v2.1. I didn't experiment this myself, so I can't confirm anything. Just in case, maybe have a look at the Chapter 18. Application servers and environments supported by Weld (GlassFish v2.1 hasn't been tested, but it doesn't mean it doesn't work).
Pascal's suggestion about upgrading to GlassFish 3 sounds probably like the most elegant approach ;)
I'd be curious to hear what prevents moving to a more recent version (not saying there can't be a reason, just wondering what the issue is here).