Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Autowired service inside a @ManagedBean @Component class is null during JSF request [duplicate]

I tried union Spring 3(MVC) with JSF 2. I have some experience in Spring and JSF, but never tried to join them before. In the end I have 2 files

@ManagedBean(name = "userBean")
@Scope
@Component
public class someBean {

  @Autowired
  private TestService testService;

  public void printString() {
    System.out.println(testService.getString());
  }
}

and

@ManagedBean(name = "studentBean")
@Scope
@Component
public class StudentBean {

  @Autowired
  private TestService testService;

  public void printString() {
    System.out.println(testService.getString());
  }
}

For these file I have right configuration for spring, jsf, and web.xml. And have .xhtml page where I start printString() for 'someBean' and for 'StudentBean'. I have the NPE in first case and 'some string' in the console in second case. The reason is simple - different bean names in the Spring context and JSF. all problems finished after

@Component => @Component("userBean") 
public class someBean {

In the debug I saw that

private TestService testService;

@Autowired
public void setTestService(TestService testservice) {
  this.testService = testService;
}

When JSF bean is creating testService sets not null, but it is null during JSF lifecycle when

public void pringString() {
  testService.blah();
}

testService is null. It is what I can't understand. Has someone deep knowledge the Spring and JSF to describe this situation in details?

like image 633
skilgal Avatar asked Feb 09 '15 23:02

skilgal


People also ask

Why Autowired is giving null?

The field annotated @Autowired is null because Spring doesn't know about the copy of MileageFeeCalculator that you created with new and didn't know to autowire it.

Is @component required for Autowired?

So the answer is: No, @Autowired does not necessarily mean you must also use @Component . It may be registered with applicationContext. xml or @Configuration+@Bean .

What is @component and @autowired in Spring boot?

This is called Spring Bean Autowiring. In java based configuration, all the bean methods are defined in the class with @configuration annotation. At runtime, Spring will provide bean definitions by reading those methods. Using @Autowired, the right dependency is assigned by the Spring Container.

What is @component and Autowired?

The @Autowired annotation allows the container to automatically inject the message property from the application-context. xml file. The container searches for String bean object in the xml file and injects it here. If multiple String beans exist, then we will get an error.


2 Answers

Both JSF and Spring can act as bean containers. The @ManagedBean annotation instructs the JSF managed bean facility to create a new instance of the class, and manage it under the given name. The @Component annotation instructs the Spring ApplicationContext to create a new instance of the class, and manage it under the given name. That is, both JSF and Spring create an instance of that class, the JSF one is reachable through EL, but the Spring one gets its dependencies injected (because, being a spring annotation, @Autowired is not understood by the JSF managed bean facility).

So you have a choice: Use the JSF managed bean facility for everything (which I would not recommend, as it is rather limited), use CDI for everything (which is an option, but does not use Spring), or use Spring for everything (which I usually do), by removing the @ManagedBean annotation, and making Spring beans accessible through EL by registering a SpringBeanFacesELResolver in your faces-config.xml. The Spring reference manual describes this in section 19.3.1.

like image 177
meriton Avatar answered Sep 30 '22 23:09

meriton


I had the same issue, it was due to the property name of @ManagedBean annotation.My backing bean looks like this

@Component
@ManagedBean(name="mainBean")
@SessionScoped
public class MainManagedBean{...}

As you can see, the name given to the bean (mainBean) is different to the default name (mainManagedBean) that the backing bean should have.

I have fixed the issue by setting the property name to "mainManagedBean". My bean becomes like this:

@Component
@ManagedBean(name="mainManagedBean")
@SessionScoped
public class MainManagedBean{...}

I wish this can help you

like image 30
Youness Marhrani Avatar answered Sep 30 '22 22:09

Youness Marhrani