I have a Session scoped bean
import javax.faces.bean.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class SessionBean implements Serializable{
I inyect the object in one Filter...
public class FiltroSeguridad implements Filter{
#Inject
private SessionBean sessionBean;
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
sessionBean.setRutaRedirect(httpRequest.getRequestURI());
}
}
But, I inyect SessionBean in the next interaction...
#Model
public class CuentaUsuarioWebBean implements Serializable{
#Inject
private SessionBean sessionBean;
public void loginUsuario() throws IOException{
sessionBean.getRutaRedirect();
}
}
But the property getRutaRedirect() returns null
I change the import by CDI annotations it still doesn't work (javax.enterprise.context.SessionScoped), same with JSF annotation (javax.faces.bean.ManagedBean and #ManagedProperty).
Thanks.
PD: Sorry for my English!
You can't mix annotations from those two packages you're using javax.faces.bean.SessionScoped for JSF, and import javax.inject.Named for CDI. Both reflect different injection mechanisms and cannot be mixed on the same bean. You have to pick both annotations(for Injection and Bean Scoping) from the same package. Use the following sets from their corresponding packages
For CDI-based bean definitions
javax.enterprise.context.SessionScoped //for bean scoping
javax.inject.Named //for bean declaration
javax.inject.Inject //for injection
For JSF-based bean definitions
javax.faces.bean.SessionScoped //for bean scoping
javax.faces.bean.ManagedBean //for bean declaration
javax.faces.bean.ManagedProperty //for bean injection
EDIT: Now I understand your requirements better, use the following construct to inject a JSF managed bean
#ManagedProperty(value="#{yourBeanName}")
SessionBean yourSessionBean;
Also note that within JSF, you can inject only beans of a wider scope than their targets e.g. you can inject a #SessionScoped bean into a #RequestScoped bean and not the other way around
But since JSF managed beans are deprecated, better to use the CDI managed ones. In that case you can inject shorter scoped beans in wider scoped ones
Forget about managed beans. It won't work with a Filter that way. If you insist on using it then do it properly by follow the answer provided here:
How implement a login filter in JSF?
Now regarding CDI, if you problem is that a specific value is null and you have verified this by actually getting a NPE or so (Since for example Eclipse debugger sometimes get's it wrong). Then double check that you used correct SessionScoped like described by kolossus and also check what BalusC said (beans.xml).
A good way to see if CDI is working is to ask the manager for the bean. Put this debug code somewhere and try it:
#Inject
BeanManager manager;
#PostConstruct
private void test() {
Bean<?> bean = (Bean) manager.resolve(manager.getBeans("ANY_NAMED_BEAN_EL_NAME"));
System.out.println(bean);
}
Related
when I tried to inject request scoped bean in application scope bean I got the following error.
Method threw 'org.jboss.weld.contexts.ContextNotActiveException' exception. Cannot evaluate com.example.flow.txn.TxnMessageProcessor$Proxy$_$$_WeldClientProxy.toString()
Code Reference:
#ApplicationScoped
public class TxnMessageObserver {
private static final Logger logger = LoggerFactory.getLogger(TxnMessageObserver.class);
#Inject
private TxnMessageProcessor processor;
//message is observed here
public void postConstruct(#Observes #Initialized(ApplicationScoped.class) Object o) {
logger.info("Subscribing to queue [{}] for msg.", queue);
consumer.subscribe(queue);
}
}
#RequestScoped
public class TxnMessageProcessor {
private static final Logger logger = LoggerFactory.getLogger(TxnMessageProcessor.class);
//all processing happens here
}
I need to process every message in request scope.
If the applicationscoped bean is constructed eagerly when the servlet context is initialized (like is the case here), there is no request context and hence no requestscoped bean.
Since it is completely unclear what you try to achieve (your code is not a minimal reproducible example, let me point you to
JEE6 #ApplicationScoped bean and concurrency
Why #Singleton over #ApplicationScoped in Producers?
(All found via this search)
Injecting a requestscoped bean is therefor dangerous and I strongly suggest to retrieve the required requestscoped bean in the specific methods or do it the other way around, inject the applicationscoped bean in the requestscoped one and call a method on it, passing in itself.
I do not know what exactly the problem cause is. But I can confirm that you can inject #ReqeustScoped beant into #ApplicationScoped. I do that in many applications with hundreds of classes and it worked out of the box.
I understand that a managed bean works like a controller, because your only task is "link" the View Layer with Model.
To use a bean as a managed bean I must declare #ManagedBeanannotation, doing that I can communicate JSF with bean directly.
If I want to inject some component (from Spring) in this managedBean I have two possibles ways:
Choose the property in ManagedBean (like "BasicDAO dao") and declare #ManagedProperty(#{"basicDAO"}) above the property. Doing it, i'm injecting the bean "basicDAO" from Spring in ManagedBean.
Declared #Controller in ManagedBean Class, then i'll have #ManagedBean and #Controller annotations, all together. And in property "BasicDAO dao" i must use #Autowired from Spring.
Is my understanding correct?
#ManagedBean vs #Controller
First of all, you should choose one framework to manage your beans. You should choose either JSF or Spring (or CDI) to manage your beans. Whilst the following works, it is fundamentally wrong:
#ManagedBean // JSF-managed.
#Controller // Spring-managed.
public class BadBean {}
You end up with two completely separate instances of the very same managed bean class, one managed by JSF and another one managed by Spring. It's not directly clear which one would actually be used in EL when you reference it as #{someBean}. If you have the SpringBeanFacesELResolver registered in faces-config.xml, then it would be the Spring-managed one, not the JSF-managed one. If you don't have that, then it would be the JSF-managed one.
Also, when you declare a JSF managed bean specific scope, such as #RequestScoped, #ViewScoped, #SessionScoped or #ApplicationScoped from javax.faces.* package, it will only be recognized and used by #ManagedBean. It won't be understood by #Controller as it expects its own #Scope annotation. This defaults to singleton (application scope) when absent.
#ManagedBean // JSF-managed.
#ViewScoped // JSF-managed scope.
#Controller // Spring-managed (without own scope, so actually becomes a singleton).
public class BadBean {}
When you reference the above bean via #{someBean}, it would return the Spring-managed application scoped bean, not the JSF-managed view scoped bean.
#ManagedProperty vs #Autowired
The JSF-specific #ManagedProperty works only in JSF-managed beans, i.e. when you're using #ManagedBean. The Spring-specific #Autowired works only in Spring-managed beans, i.e. when you're using #Controller. Below approaches are less or more equivalent and cannot be mixed:
#ManagedBean // JSF-managed.
#RequestScoped // JSF-managed scope.
public class GoodBean {
#ManagedProperty("#{springBeanName}")
private SpringBeanClass springBeanName; // Setter required.
}
#Component // Spring-managed.
#Scope("request") // Spring-managed scope.
public class GoodBean {
#Autowired
private SpringBeanClass springBeanName; // No setter required.
}
Do note that when you have the SpringBeanFacesELResolver registered in faces-config.xml as per the javadoc,
<application>
...
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
and thus you can reference Spring managed beans in EL via #{springBeanName}, then you can just reference them in #ManagedProperty too, as it basically sets the evaluated result of the given EL expression. The other way round, injecting a JSF managed bean via #Autowired, is in no way supported. You can however use #Autowired in a JSF managed bean when you extend your bean from SpringBeanAutowiringSupport. This will automatically register the JSF managed bean instance in Spring autowirable context during constructor invocation, which means that everything #Autowired will be available in #PostConstruct and later.
#ManagedBean // JSF-managed.
#ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport implements Serializable {
#Autowired
private SpringBeanClass springBeanName; // No setter required.
#PostConstruct
private void init() {
// springBeanName is now available.
}
}
Or when your architecture doesn't allow extending beans from a different base class, then you can always manually register the JSF managed bean instance in Spring autowirable context as below. See also How to integrate JSF 2 and Spring 3 (or Spring 4) nicely for the trick.
#ManagedBean // JSF-managed.
#ViewScoped // JSF-managed scope.
public class GoodBean implements Serializable {
#Autowired
private SpringBeanClass springBeanName; // No setter required.
#PostConstruct
private void init() {
FacesContextUtils
.getRequiredWebApplicationContext(FacesContext.getCurrentInstance())
.getAutowireCapableBeanFactory().autowireBean(this);
// springBeanName is now available.
}
}
#XxxScoped vs #Scope
Spring's #Scope has limited support for JSF scopes. There's no equivalent for JSF's #ViewScoped. You'd basically either homegrow your own scopes, or stick to manually registering the JSF managed bean instance in Spring autowirable context as shown above.
And, from the other side on, Spring WebFlow was taken over in JSF 2.2 via new #FlowScoped annotation. So if you happen to be on JSF 2.2 already, then you don't necessarily need to use Spring WebFlow if you solely want the flow scope.
CDI - trying to unify it all
Since Java EE 6, CDI is offered as standard alternative to Spring DI. It has respectively #Named and #Inject annotations for this and also its own set of scopes. I'm not sure how it interacts with Spring as I don't use Spring, but #Inject works inside a #ManagedBean, and #ManagedProperty inside a #ManagedBean can reference a #Named bean. On the other hand, #ManagedProperty doesn't work inside a #Named bean.
The purpose of CDI is to unify all different bean management frameworks into only one specification/inteface. Spring could have been a full CDI implementation, but they choosed to only partially implement it (only JSR-330 javax.inject.* is supported, but JSR-299 javax.enterprise.context.* not). See also Will Spring support CDI? and this tutorial.
JSF will be moving to CDI for bean management and deprecate #ManagedBean and friends in a future version.
#Named // CDI-managed.
#ViewScoped // CDI-managed scope.
public class BetterBean implements Serializable {
#Inject
private SpringBeanClass springBeanName; // No setter required.
#PostConstruct
private void init() {
// springBeanName is now available.
}
}
See also:
When is it necessary or convenient to use Spring or EJB3 or all of them together?
JSF Service Layer
Backing beans (#ManagedBean) or CDI Beans (#Named)?
Using JSF as view technology of Spring MVC
How to install and use CDI on Tomcat?
There is another way to use Spring-managed beans in JSF-managed beans by simply extending your JSF bean from SpringBeanAutowiringSupport and Spring will handle the dependency injection.
#ManagedBean // JSF-managed.
#ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport {
#Autowired
private SpringBeanClass springBeanName; // No setter required.
// springBeanName is now available.
}
The easy way to do this is via XML. I used #Component in already made jsf managed bean but #Autowired did not work because managed bean was already there in faces-config.xml. If it is mandatory to keep that managed bean definition along with its managed property in the xml file then it is suggested to add the spring bean as another managed property inside the managed bean tag. Here the spring bean is there defined in spring-config.xml(can be autowired somewhere alternately). please refer
https://stackoverflow.com/a/19904591/5620851
edited by me. I suggest to either implement it altogether through annotation #Managed and #Component or via xml for both.
You can autowire individual beans without #Autowired by leveraging getBean of the current WebApplication context.
Please refer to #BalusC's answer for more details. This is just a slight modification over his example:
#ManagedBean // JSF-managed.
#ViewScoped // JSF-managed scope.
public class GoodBean implements Serializable {
// #Autowired // No Autowired required
private SpringBeanClass springBeanName; // No setter required.
#PostConstruct
private void init() {
WebApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
this.springBeanName = ctx.getBean(SpringBeanClass.class);
// springBeanName is now available.
}
}
I am trying to use and understand CDI, when I use #Inject in a simple pojo class, it throws me NPE.
example
Greeting.java
public Class Greeting {
public String greet() {
System.out.println("Hello");
}
}
Test.java
import javax.inject.Inject;
public class Test {
#Inject
private Greeting greeting;
public void testGreet() {
greeting.testGreet();
}
}
When I call testGreet() it throws NPE, why is the greeting instance null. Does #Inject way of adding dependency only be used in container managed bean?
Note: jar is not the problem here.
TL;DR:
#Inject-annotated fields are only populated for container-instantiated beans.
Long version:
The CDI container provides you a lot of utilities for easily injecting dependencies to your beans, but it doesn't work by magic. The container can only populate the annotated fields of a client bean if the client bean itself was instantiated by the container. When the container is instantiating the object the sequence of events is as follows:
Your bean's constructor is called.
#Inject-annotated fields (and some other
annotations, #PersistenceContext and #EJB for instance) are
populated.
#PostConstruct-annotated no-args method is called.
Your bean is finished.
You're facing a classic bootstrapping problem, how to move from non-container-managed code into container-managed code. Your options are:
Get access to an instance of BeanManager from your JavaEE container via JNDI lookup. This is technical and a bit clumsy.
Use a CDI extension library such as Apache DeltaSpike. (Example: BeanProvider.getContextualReference(Test.class, false);)
Modify your application to start in a situation where you can inject your Test class rather than calling new Test();. This can be done for example by setting up a startup singleton ejb, which calls your test in it's #PostConstruct-annotated initialisation.
Hope this helps.
You need a JavaEE container, and than you need to define Greeting and Test as managed beans. After that you can inject one in another.
Try to take a look at:
https://docs.oracle.com/javaee/6/tutorial/doc/girch.html
Your class should be implemented from Serializable for being injectable as a "CDI Bean"
I'm working with some existing code and it is doing things I haven't seen before. I've dealt with autowiring prototype beans into singletons using method injection or getting the bean from the context using getBean(). What I am seeing in this code I am working on is a bean that is a prototype and retrieved using getBean(), and it has autowired dependencies. Most of these are singleton beans, which makes sense. But there is an autowire of another prototype bean, and from what I see, it does seem like it is getting a new bean. My question is when you autowire a prototype into a prototype, will that give you a new instance? Since the autowire request is not at startup but rather when this bean is created, does it go and create a new instance? This goes against what I thought about autowire and prototype beans and I wanted to hear an answer from out in the wild. Thanks for any insight. I'm trying to minimize my refactoring of this code as it is a bit spaghetti-ish.
example:
#Scope("prototype")
public class MyPrototypeClass {
#Autowired
private ReallyGoodSingletonService svc;
#Autowired
private APrototypeBean bean;
public void doSomething() {
bean.doAThing();
}
}
#Scope("prototype)
public class APrototypeBean {
private int stuffgoeshere;
public void doAThing() {
}
}
So when doSomething() in MyPrototypeClass is called, is that "bean" a singleton or a new one for each instance of MyPrototypeClass?
In your example, the APrototypeBean bean will be set to a brand new bean which will live through until the instance of MyPrototypeClass that you created is destroyed.
If you create a second instance of MyPrototypeClass then that second instance will receive its own APrototypeBean. With your current configuration, every time you call doSomething(), the method will be invoked on an instance of APrototypeBean that is unique for that MyPrototypeClass object.
Your understanding of #Autowired or autowiring in general is flawed. Autowiring occurs when an instance of the bean is created and not at startup.
If you would have a singleton bean that is lazy and that bean isn't directly used nothing would happen as soon as you would retrieve the bean using for instance getBean on the application context an instance would be created, dependencies get wired, BeanPostProcessors get applied etc.
This is the same for each and every type of bean it will be processed as soon as it is created not before that.
Now to answer your question a prototype bean is a prototype bean so yes you will receive fresh instances with each call to getBean.
Adding more explanation to #Mark Laren's answer.
As explained in Spring 4.1.6 docs
In most application scenarios, most beans in the container are
singletons. When a singleton bean needs to collaborate with another
singleton bean, or a non-singleton bean needs to collaborate with
another non-singleton bean, you typically handle the dependency by
defining one bean as a property of the other. A problem arises when
the bean lifecycles are different. Suppose singleton bean A needs to
use non-singleton (prototype) bean B, perhaps on each method
invocation on A. The container only creates the singleton bean A once,
and thus only gets one opportunity to set the properties. The
container cannot provide bean A with a new instance of bean B every
time one is needed.
Below approach will solve this problem, but this is not desirable because this code couples business code with Spring framework and violating IOC pattern. The following is an example of this approach:
// a class that uses a stateful Command-style class to perform some processing
package fiona.apple;
// Spring-API imports
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class CommandManager implements ApplicationContextAware {
private ApplicationContext applicationContext;
public Object process(Map commandState) {
// grab a new instance of the appropriate Command
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
protected Command createCommand() {
// notice the Spring API dependency!
return this.applicationContext.getBean("command", Command.class);
}
public void setApplicationContext(
ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
So, there are 2 desirable ways to solve this problem.
1. Using Spring's method injection
As name suggests, Spring will implement & inject our abstract method by using #Lookup annotation from Spring 4 or tag if you use xml version. Refer this DZone article.
By using #Lookup.
from Java Doc...
An annotation that indicates 'lookup' methods, to be overridden by the
container to redirect them back to the BeanFactory for a getBean call.
This is essentially an annotation-based version of the XML
lookup-method attribute, resulting in the same runtime arrangement.
Since:
4.1
#Component
public class MyClass1 {
doSomething() {
myClass2();
}
//I want this method to return MyClass2 prototype
#Lookup
public MyClass2 myClass2(){
return null; // No need to declare this method as "abstract" method as
//we were doing with earlier versions of Spring & <lookup-method> xml version.
//Spring will treat this method as abstract method and spring itself will provide implementation for this method dynamically.
}
}
The above example will create new myClass2 instance each time.
2. Using Provider from Java EE (Dependency Injection for Java (JSR 330)).
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
#Component
public static class SomeRequest {}
#Service
public static class SomeService {
#Autowired
javax.inject.Provider<SomeRequest> someRequestProvider;
SomeRequest doSomething() {
return someRequestProvider.get();
}
}
The above example will create new SomeRequest instance each time.
I'm fresh new in Google Guice framework and i have a question regarding injecting in guice servlet and using RequestScope. Ok let me give some example from my code just to make the things clearly.
I have a bean class for example Bean ..
#RequestScope
public class Bean {
private String user;
private String pass;
// constructor which is #inject
// getters and setters
}
Here i've got a servlet
#Singleton
public class MainServlet extends HttpServlet {
doGet(HttpServletRequest request, HttpServletResponse response) {
.... some code
Injector injector = Guice.createInjector();
ValidUser validUser = injector.getInstance(ValidUser.class)
// Here i got the below exception
}
}
com.google.inject.ConfigurationException: Guice configuration errors:
1) No scope is bound to com.google.inject.servlet.RequestScoped.
at Bean.class while locating Bean
It's interesting here that servlet scope is singleton as we know.
And also how can i get from the http request - Bean instance?? because as far as i understand after a instance of a Bean class is injected it goes in the http request, right?
Any help or example is welcome.
Thanks
Br
You're creating and using an Injector inside the doGet method on your servlet... it has no chance to be aware of scope or of the current request or anything!
Guice Servlet requires that you set up all requests to go through the GuiceFilter and that you create a subclass of GuiceServletContextListener that creates the Injector that your whole application will use. This is all described in Guice user guide in the Servlets section.
Once you've done that, you can #Inject things in to your MainServlet (even using an #Inject annotated constructor). To get a request scoped instance of Bean inside the servlet, you'd need to inject a Provider<Bean> (since Bean has a smaller scope than the singleton servlet). Within a request, you can call beanProvider.get() to get the Bean for the current request.
Note that servlets are singletons because that's how they work in the normal Java servlet world as well... they're each only created once per application and that single instance is used for all requests to that servlet.