Problems with Injection (Using vaadin) - java

I am newbie with EJB and Injections...
I am currently using Vaadin framework with CDI
I have been trying to using injection but i have not could do it...
In my Vaadin UI class MyVaadinUI i have tried...
CDIUI("")
#SuppressWarnings("serial")
public class MyVaadinUI extends UI {
#EJB
UserController userController;
#Override
protected void init(VaadinRequest request) {
System.err.println("desde controller "+userController.getAll().size());
}
}
UserController
#Stateless
public class UserController {
#EJB
IUserDAO userDao;
public List<User> getAll() {
return userDao.findAll();
}
}
and it works!!
but when I do not inject UserController, it does not work... In other words when I instance the class UserController the injection in this class does not work...
Code does not work
CDIUI("")
#SuppressWarnings("serial")
public class MyVaadinUI extends UI {
#Override
protected void init(VaadinRequest request) {
UserController userController = new UserController();
System.err.println("desde controller "+userController.getAll().size());
}
}
Somebody can explain me why?
Thanks
Nicolas

Only in injected objects will have its dependencies injected. If you create an object with new all field having #inject, #ejb or #resource will not be injected.
In your case you create UserController like this:
UserController userController = new UserController();
and so this field will not be injected:
#EJB
IUserDAO userDao;
And therefore getAll() will throw a NullPointerException.
I use vaadin and cdi for projects. I'd recommend to use injection for almost everything or not at all. I inject my uis, views, own components... (and do not create them with new) so it is possible to inject ejb beans or other things into them. If you are using it only sometimes you are ending up with am mixture of injection and normal object creation and will have to pass around injected objects to other object you instantiated yourself. In another project of mine this happened and got really problematic for future changed in the code.

Related

#Autowired attribute that needs a parameter to be instantiated

I'm new to spring boot, and I need to know how to use #autowired in an attribute that needs parameters to be instantiated.
Please bear in mind the following illustrative situation. It would be something like this:
public class MyClassA{
public SpecificClass myMethod(){
//some logic
}
}
public class MyClassB extends MyClassA{
#Autowired
MyComponent myComponent (myMethod()); //here is my doubt, because my component needs a parameter to be built
}
#Component
public class MyComponent{
public MyComponent(SpecificClass foo){
this.foo=foo;
}
That's not really proper design if your intention is to work with dependency injection. There shouldn't be a direct dependency to the superclass' method like that. Injecting the dependencies indirectly as you're supposed to do would result in something like the following
public class MyClassB extends MyClassA {
#Autowired
private MyComponent myComponent;
}
#Configuration
public class SomeConfig {
#Bean
#Autowired
public MyComponent createComponent(SpecificClass foo) {
// SpecificClass is also injected, providing another layer of indirection
return new MyComponent(foo);
}
}
#Autowired only tells Spring to inject a component into a constructor, field, or method parameter. The injected component is instantiated by the bean container before that. I assume what you are looking for is a way to create MyComponent in such a way that it also receives a Spring Bean.
In your example you could achieve this with the following
#Configuration
public class MyClassA{
#Bean //the bean would have the name 'myMethod', so maybe change that
public SpecificClass myMethod(){
//some logic
}
}
//this needs to be a component, service, ...
#Component
public class MyClassB {
#Autowired
MyComponent myComponent;
}
#Component
public class MyComponent{
#Autowired //Spring wires the Bean 'myMethod' in here, autowired is not needed in the latest Spring Versions
public MyComponent(SpecificClass foo){
this.foo=foo;
}
}
This is a basic Spring question, and not specific to Spring Boot. To better understand wiring you can take a look at the Spring 4 Framework Reference Documentation.

Instantiating a #autowired bean inside #postconstruct method inside controller, spring

I want to call a common service for all the controllers to get a commmon ModelAndView object with some common objects inside it.
So I created a superclass for all the controllers- BaseController, and I am initiating the common model object inside the constructor of BaseController by calling the a method, initCommonData which uses a #Autowired bean CommonDataService, which is not present at the construction time of object and returns null, so what I should do to get #autowired dependency inside constructor.
FYI - I am using this common servie and common data to get some commod data which will be used on each jsp in header and footer of the site.
So if there is some another way of doing this without calling the common service in each controller method, in each controller please suggest.
Here is my code -
BaseController
#Controller
public class BaseController {
#Autowired
private CommonDataService commonDataService;
protected ModelAndView model;
public BaseController() {
this.initCommonData();
}
public void initCommonData(){
this.model = new ModelAndView();
this.model.addObject("headerData",commonDataService.getHeaderData());
this.model.addObject("footerData",commonDataService.getFooterData());
}
subclass controller -
#Controller
public class HomeController extends BaseController {
#Autowired
CategoryService categoryService;
#Autowired
CompanyService companyService;
#RequestMapping(value = { "", "/", "home" })
public ModelAndView homePage() {
model.setViewName("home");
.
.
.
model.addObject("name", value);
model.addObject("name2", value2);
return model;
}
CommonServiceClass -
#Service
public class CommonDataService {
#Autowired
CompanyService companyService;
#Autowired
CategoryService categoryService;
#Cacheable
public List<Category> getHeaderData(){
return categoryService.getTopCategoryList();
}
#Cacheable
public List<Company> getFooterData(){
return companyService.getTopCompanyList();
}
Please suggest if there is any other good way of doing this, getting common data from server to jsp.
Whatever #Andreas has suggested is the best solution i.e., mark your BaseController as abstract and use #Postconstruct. This makes perfect scense because BaseController itself does not own any url mappings in your case, so do not mark it as #Controller
Because of any reason, if you are looking for other options, you can consider marking your BaseController as #Component and use #Postconstruct for initCommonData so that this method will be called automatically once the BaseController bean has been loaded by the spring container:
#Component
public class BaseController {
#Autowired
private CommonDataService commonDataService;
protected ModelAndView model;
#Postconstruct
public void initCommonData(){
this.model = new ModelAndView();
this.model.addObject("headerData",commonDataService.getHeaderData());
this.model.addObject("footerData",commonDataService.getFooterData());
}
}
First, remove #Controller from your base class. You might even make the class abstract to help indicate/document that it must be subclassed.
Next, don't call initCommonData() from the constructor. Spring cannot inject field values until after the object is created, so there is no way for Spring to wire in commonDataService before constructor completes.
Instead, annotate initCommonData() with #PostConstruct:
public class BaseController {
#Autowired
private CommonDataService commonDataService;
protected ModelAndView model;
#PostConstruct
public void initCommonData(){
this.model = new ModelAndView();
this.model.addObject("headerData",commonDataService.getHeaderData());
this.model.addObject("footerData",commonDataService.getFooterData());
}

java spring #component scope and HttpServletRequest

One of my classes deals with HttpServletRequest and is a component like this:
#Component
public class AuthorizationService {
#Autowired
HttpServletRequest request;
public Boolean authorize(Integer fetId) {
...play with headers, db and other stuff...
}
and is used somewhere else like this
public class CarRestController {
#Autowired
CarService service;
#Autowired
AuthorizationService authorizer;
#RequestMapping(method = RequestMethod.GET)
public List<Car> get()throws Exception {
authorizer.authorize(666);
...
return cars;
}
My worry is that since AuthorizationService is a #component, it will be a singleton by default and therefore there can only be one request that will be swapped by newer ones coming as it is processed.
Should I do this to solve the problem?
#Component
#Scope("prototype")
public class AuthorizationService {
Many Thanks
Remove the #Scope on the service and don't worry, your controller is also a singleton (because it's managed by spring).
BTW: you are missing a #Controller on your controller
Some reading:
Spring framework reference: The IoC container
Must Spring MVC Classes be Thread-Safe
Spring takes care of request scoped object like HttpServletRequest automatically. Remove #Scope and you should be fine.

Spring Autowired gwt RemoteServiceServlet implement class is null

I have two gwt RemoteServiceServlet in my project which has use GWT framework as below
#RemoteServiceRelativePath("AuthService")
public interface AuthService extends RemoteService {
}
public class AuthServiceImpl extends RemoteServiceServlet implements AuthService
{
#Autowired
private StoredService storeService;
}
#RemoteServiceRelativePath("webService")
public interface WebService extends RemoteService
{
}
public class WebServiceImpl extends RemoteServiceServlet implements WebService
{
#Autowired
private LogService logService;
}
Both the #Autowired of StoreService and LogService are work. But when I try to autowired WebService in AuthService, it will be null at runtime.
The interface and implements are in different package, which is com.test.client.service and com.test.server.service respectively.
I have confirm my SpringApplication-context.xml has below declare:
<context:component-scan
base-package="com.test.client.service, com.test.server.service
>
Also try to add #Service, #Component or #Configurable on WebServiceImpl, but still not works.
Override the init() of WebServiceImpl is also not work either.
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
WebApplicationContextUtils.getWebApplicationContext(config.getServletContext())
.getAutowireCapableBeanFactory().autowireBean(this);
}
Is that because the RemoteService cause the autowired not work correctly?
Any help is appreciated.
Thanks
I use the following to integrate GWT-RPC into Spring. I wrote it 6 years ago and never saw the need to change it. It is old-school and it works. It models GWT-RPC services as Spring MVC controllers, which they are. You can autowire anything into those controllers.
I mentioned it in a different answer, so I'll just post a link: https://stackoverflow.com/a/30838630/4982193

Creating unique instances in spring mvc 3 parent Controller

I'm developing a web app using the Spring 3 framework.
So, I have the next hierachy level in my controllers package:
#Controller
public class BaseController {
#Autowired
#Qualifier("problemService")
protected ProblemService problemservice;
#Autowired
#Qualifier("codeService")
protected CodeService codeservice;
#Autowired
#Qualifier("userService")
protected UserService userservice;
#Autowired
#Qualifier("sessionRegistry")
protected SessionRegistry session;
.....
}
with children
#Controller
public class CodeController extends BaseController{
...
}
#Controller
public class ProblemController extends BaseController{
...
}
What i want is all these service of BaseController available to the children, but more like static resources, that is, all children share an unique instance of the father's services, and not a new instance of each as inheritance does.
In that way, I tried this for each resource in BaseController:
#Autowired
#Qualifier("problemService")
protected static ProblemService problemservice;
but Spring throws a NullPointerException.
So, is my idea at least correct? I mean, i do want to do what i said, but i dont know if it is a good approach at least.

Categories

Resources