JSF2 managed bean annotation + scope + injection confusion - spring

I would like to achieve this idealism :
To have only 1 implementation for the JSF Bean container, like to use only Spring or Weld but not both. Currently i am using Spring for my backend, so i prefer Spring.
To have only 1 annotation, to choose between #ManagedBean, #Named, #Model
To be able to use all supported scopes, like #RequestScoped, #SessionScoped, #ViewScoped, #FlashScoped, maybe also #ConversationScoped
The JSF Beans could be injected with spring-managed-services (The backend services), perhaps using #Inject or #Autowired
So far i've been finding no best combination to achieve these because as far as i know, please correct me if i am wrong, :
#ManagedBean can not be injected with spring services ?
#Named can be injected with spring services using #Inject, but #Named is using Weld. Can i just use spring to managed the #Named instead of Weld ?
#Named doesnt support #ViewScoped and FlashScope ?
Please share your thoughts and experiences.
Thank you :-)
UPDATE 15 March 2011
Found an interesting page that describes how to replace Jboss Weld with Spring as the JSR 299 CDI implementation. So basically, the question number 2 is answered. Number 1 is also answered indirectly since i can now inject spring services.
But still, the number 3 question remains. I would find very helpful if i can use the #ViewScoped and Flash Scope in the #Named, something like this article. Flash scope implementation has yet to be seen, but the closest one i can get so far is this page.
Hopefully, replacing weld with spring as the jsr 299 implementation will still enable me to use #ConversationScoped.
Gotta test things now, wish me luck :-)
UPDATE 18 MARCH 2011
Successfully make use of Spring 3 instead of weld to do the #Named, #Inject. The important thing is to set the el-resolver in the faces-config.xml.
AFAIK, Spring 3 currently doesnt support CDI yet, so bye2 #ConversationScoped.
For the scoping, i must still use #Scope("request") or #Scope("session"), but if i prefer the #RequestScoped (javax.enterprise.context.RequestScoped) and #SessionScoped, i can make use of the bridge provided from this article.
The Scope("view") for spring from this article works like magic :-)
One problem remain though, how to pass objects between Scope("view")-beans ..
Wish me luck !
update
Ahhh .. finally done ..
Passing the variables using Flash provided by JSF2 really works like magic.
I dont need an 3rd party implementation for that.
So basically, i can do without weld, but with spring, with the common scopes available, including the view scope, dan can pass between beans using the flash object.
One thing missing is the conversation scope, which isnt a major problem to me yet.
Hopefully the future spring can support this conversation scope.
Cheers :-)

I can successfully Inject Spring bean using ManagedProperty annotation like below. This is on JSF Managed Bean. Spring bean is for backend and I prefer spring for backend.
#ManagedProperty(name="userRepository", value="#{userRepository}")
private UserRepository userRepository;
//Setter and/or Getter
value is the most important thing here. It's actually the bean name of spring. I hope this helps.

Weld (actually, the reference implementation of JSR-299 Context and Dependency Injection, also known as Java EE 6 CDI) was less or more invented to supplant Spring in Java EE 6 environments. I would suggest to use Java EE 6 CDI instead of Spring. Why would you use a 3rd party framework when Java EE 6 provides the same functionality out the box?
If the Spring backend really cannot be changed, then I'd suggest to stick to it and not to intermix with Java EE 6 CDI annotations to save yourself from confusions and maintenance headache.

Related

workaround for JAVASERVERFACES-3947

Does anyone know a workaround for https://java.net/jira/browse/JAVASERVERFACES-3947 ?
In my project , I am using primefaces 5.3 , mojarra 2.2.12
wilfly 8.2.1
I profile the application , and I see ViewScopedManaged beans are not garbaged collected , and the heaps keeps increasing and increasing until there is a memory leak
In faces-config, I have this to integrate with Spring:
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
I think my issue is related to https://java.net/jira/browse/JAVASERVERFACES-3947 . Does anyone know a workaround ? I think there are some jsf parameters to configure the max number of views scopbed beans in memnory ? will it work out ?
This is an example of a bean class:
#ManagedBean
#ViewScoped
#Data
public class JSFBean {
//springBeanImpl is a Spring bean
#ManagedProperty(value = "#{springBeanImpl }")
private SpringBean springBean;
}
In our last JSF project, we did the following:
#ManagedBean
#ViewScoped
public class CountryBean extends SpringBeanAutowiringSupport {
#Autowired // you can also use #Inject
private SpringBean springBean;
}
So you don't use the newer CDI Annotations, but the 'old' ones from JSF. By extending your class from SpringBeanAutowiringSupport, Spring will handle the dependency injection. I suppose the JSF annotations will be removed one day and be completely replaced by CDI annotations. So that might not work in future releases of JSF.
About the garbage collection - are you sure that they are not removed at some time? Be aware that by default the last 25 Views are kept in memory. This link JSF 2.2 Memory Consumption: Why does Mojarra keep the ViewScoped Beans of the last 25 Views in Memory? explains it a little. Hopefully those parameters are better documented in JSF 2.3.
Anyway, as balusc mentioned - Spring and JSF are currently not the best combination since JSF relies more and more on CDI. I personally think that it is a pity that the current situation is like that. This was one of the main reasons why we stopped using JSF in new projects. It is just to unclear whether JSF and Spring will be less or more compatible in coming releases.

Injecting spring beans into legacy web app POJOs [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 7 years ago.
In order to provide POJOs in my legacy web app (Tomcat 8.0.26) with the ability to send ActiveMQ messages I've taken the recommendation to introduce Camel (2.15.2) / Spring (4.2.1) into the app to purely for the purpose of managing pooled MQ connections. I'm hoping there isn't an easier way.
Doing things the Spring way I'm thinking everything would need to be based around an MVC architecture with HTTP servlet aware controllers having access to the servlet context and therefore the Spring context in order to inject beanFactory beans into classes annotated with #Controller and #Service (and in fact there must be a Spring #Controller class that enables Spring to inject the #Service class.
However, as I've stated this is legacy code that will not be using the spring web framework.
After much pain it seems that the only way I can get beanFactory beans injected into my POJOs is to go the AspectJ and Weaving route. Before I go down this road can someone tell me that this is currently the best approach (what I've read describing this solution is from 2011 Can't get Spring to inject my dependencies - Spring Newbie) ? Can you point me to documentation and a working example?
Many thanks.
1) aspectj with #Configurable
In your #Configuration annotated class/es
you can add some more annotations
#Configuration
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
#EnableSpringConfigured
#EnableAspectJAutoProxy
to enable aspectj and the #Configurable annotation,
you need to import the aspectj lib to your project and add the spring tomcat instrumentable java agent in your tomcat lib folder (give a look here, it exaplains how to configure tomcat) http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.html
this is not going to help you if you are going to create your pojos using "new"
MyPojo p = new MyPojo(); // no black magic for this, you will need to satisfies the dependencies yourself) but that would be helpful for example when you load some entities through a framework like hibernate and you want to inject something into them.. #Configurable it's an option that can be evaluated in those cases, for what you describe I would rather not use it.
2) You can have some static methods that uses some static set spring-beans and use them from your pojos, something like
class Util{
private static SprintBeanWithJmsSupport x;
public static setSpringBeanToHandleJmsMessages(SprintBeanWithJmsSupport x){
Util.x = x;
}
public static sendJmsMessage(JmsMessage m){
x.sendMessage(m)
}
}
and you can go with Util.sendJmsMessage(...)
this is a bit shitty but it does the work, I don't personally like this approach
3) set your spring beans in your pojo when they need to use them (maybe behind some nice interfaces that suit your domain)
if you go with spring mvc you will likely end up having some controllers that will use some services (generally they handle security / db access and are the entry point to start the "use cases"), as everything wthin these layers is handled by spring it will be very simple to pass the spring-bean to handle jms messaging to your pojos, this seems to me quite a nice way to handle the problem
I went mostly based on memory and something may not be completely accurate, plus my english is .. what it is, so hope this can be helpful anyway.

Java EE 6 / 7 equivalent for Spring #Configuration

Is there a Java EE 6 / 7 equivalent annotation for Spring's #Configuration?
If the answer is yes then are the equivalents for its surrounding annotations, such as #ComponentScan and #EnableWebMvc?
I did, of course, look for it in Java EE 6 / 7 (I admit I skipped a paragraph here and there), in javadocs (specifically among annotations), in Spring doc, tutorials, blogs, SO and Google.
JEE CDI has also an annotation of creating bean programmatically and exposing them, so it offers bean factories, called producers:
https://dzone.com/articles/cdi-and-the-produces-annotation-for-factory
CDI offers Producer methods (annotated with #Produces) which is the equivalent of #Bean in spring. You can than implement Producers classes that are beans which contain a bunch of producer methods. However, this is by far not as powerful as a spring configuration since as far as I am aware of, there is no possibity to e.g. "import" other configurations (producer classes).
This makes it especially difficult to test CDI applications.
You can either
heavily use mocks to test a single CDI bean to totally avoid injected objects
blow up your test class just to create the instance under test with all dependencies
use testing frameworks like CDI-Unit that creates the beans for you
With 1. Test Driven Development becomes almost impossible and tests have always to be adapted when implementation changes, even if the contract does not change.
With 2. you end up in a lot compiler errors in tests as soon as dependencies between your Beans change
With 3. you need to point your testing framework to the implementation of your beans. Since there exists no Configuration that knows about all beans, the test needs to know about it. Again, if things change your tests will break.
I admit... I don't like CDI ;-P
The javax.servlet.annotation package defines a number of annotations to be used to register Servlet, Filter, and Listener classes as well as do some other configuration, for example, security.
You can also use the ServletContainerInitializer class to configure your ServletContext through Java instead of through the XML deployment descriptor. Spring provides its own implementation of ServletContainerInitializer in which case all you have to do is create a class that implements WebApplicationInitializer and does servlet, filter, and listener registration and leave that class on the classpath.
Examples abound in the javadoc.

Dynamic dependency injection in jsf 2 or spring 3

I have 3 implementations of an interface, and in order to instantiate one of them I need to check a parameter from the database.
I was planning to do it with the factory pattern, but since I'm using JSF 2 dependecy injection in the rest of my application I was wondering if
there's a way to do that, is it possible to do the dependency injection dinamically?
can I indicate somehow a method or something to pick up the correct implementation at each moment?
For the backend I'm using spring core, so a way to do that with the spring context would work to.
I'm using Annotations for everything (#Autowired for Spring, #ManagedProperty for JSF).
EDIT: The project will be deployed on a Tomcat server.
I suggest you to use CDI in your JSF project, you can then use programmatic injection.
You should start with adding CDI Qualifiers to your interface implementations (you will basically create custom annotation for each implementation - tutorial). Then you can use something like
#Named //similar to ManagedBean
#RequestScoped
public Bean {
#Inject
#Any
Instance<YourInterface> yourInterface;
public void someMethod() {
if(someCondition) {
InterfaceImpl impl = yourInterface.select(new SomeOfYourQualifiers()).get();
}
}
}
Source
Also you you don't have to use Autowired in favour of Inject. I am also sure that there is some Spring way how to to this but I will leave that to some Spring expert here:-)
EDIT
According to this answer is really possible to run CDI on Tomcat. You will also find some tutorials like this one. And Spring approach could be using AutowireCapableBeanFactor but as I say, I don't know Spring much so it's just a wild gues:-)

CDI Bean accessing Spring beans?

I know this sounds strange, mixing CDI (Weld) and Spring for the controller.
But imagine this situation :
With CDI, i can make use of the #ConversationScoped, which is one of my requirement (And so far i dont know whether i can use spring for this kind of scope, because if i can, i could just replace Weld with Spring, with the el-resolver in faces-config.xml)
My services objects(#Service) along with the DAOs(#Repository) are to be managed by Spring
Now one question arise is that, inside my controller, how can i access my service object ?
Something like this wouldnt work i think :
#Named
#ConversationScoped
public class MyBean {
#Named
private SomeOtherBeanManagedByCDI myOtherBean; // this will work
#Autowired
private MySpringBean mySpringBean; // dont think that this will work
....
}
Any ideas on how to make use of spring beans inside a cdi bean ? Thank you !
update
I've just tested the solution from this article, and so far it works fine, and i feel relieved.
Thank you !
Rick Hightower wrote a nice Extension library which supports to inject Spring beans into CDI beans and vice versa:
http://rick-hightower.blogspot.com/2011/04/cdi-and-spring-living-in-harmony.html
There is still a good accepted answer and some good edits in the OP, but I think there still is time to point out the Seam Spring module.
Also, if you're trying to manage state across a series of pages, and want the effective of conversation management for Struts or JSF or Spring MVC, Spring Web Flow provides just what you need, complete with flow-scoped beans that live for the duration of a flow, more or less equivalent to a conversation in Seam / CDI. If you want a more long lived flow managment solution, the Activiti SPring module makes it dead simple to configure some beans that live for the duration of the process scope, akin to the functionality that Seam had for jBPM.

Resources