I have a stateless Bean with following heirarchy and present
accountserver , accountserverBean implements accountserver.
with there corresponding ejb-jar.xml and weblogicjar.xml
Then I have my spring Bean with the following
payload.java with corressponding spring.xml
So Inside the spring libs folder I have added account.jar
So how can I call method present in accountserverBean from payload class????
Also I have used the below Code in payload.java
Context ctx=new InitialContext();
accountserver as=(accountserver)ctx.lookup("java:com/accountserver");
But this doesnt work.
Since both are in same context I can call the EJB method
Please provide me with solution
I guess you want to integrate EJB and Spring applications. Did you try this: http://static.springsource.org/spring/docs/2.5.x/reference/ejb.html ?
Related
I'm trying to get a better understanding of the #Autowired annotations component scanning, but all the examples I found so far use context.getBean(..) at some point to get at least one Bean to start with.
I also read that doing that is considered bad practice , but I can't seem to find any information on how to do it without context.getBean(..)
Could somebody please enlighten me with an example and information on how to do this ?
Define your bean in xml and use
<context:component-scan base-package="com" />
<mvc:annotation-driven />
Bean def
<bean id="processEngine" class="com.processEngine">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
now you can get bean as following
#Autowired
private ProcessEngine processEngine;
how it works
spring scans the bean's recipes either from xml or java configuration. then spring creates a beanDefinitions which are 'loaded' into BeanFactory. BeanFactory triggers a set of BeanPostProcessors (BPP) which are scanning classes for particular annotations like Autowired/Resource/PostProcessor and etc. and do appropriate actions. in case when your class contains #Autowired annotation, AutowiredAnnotationBeanPostProcessor would auto wire required field (dependencies), and when creation of an object is done and all BPP worked out, object is ready to be used by the app, from this point your code can get 'ready' objects from container.
there are some cases when you would need to access this beans from the code which is out of spring's control and not managed by container. in order to do so, you would need to get the ApplicationContext (container) and call #getBean specifying either name or type. using applicationContext directly is not a good practice because there are some problems that you can come to, f.ex. id of a bean might be changed and if you refer to bean by id then NPE would be thrown.
configuration
there are several approaches to configure spring to scan the classes for finding bean recipes. one would be defining component-scan, in this case classes which are located in the path that you've set and having any of valid spring annotations like #Component, #Service, #Repository, #Controller (for web container) would be considered. another way would be specifying each bean separately using <bean> or #Bean.
examples.
if you want to create a web app then you should see DispatcherServlet with ContextLoaderListener classes. this classes would boot your app and load everything according to configuration. f.ex. here,
but if you want to create a desktop app, then you would end up with something like this
From time to time (usually when not using Spring Boot), I use something along the lines of the following code:
public static <T> T autowire(ApplicationContext ctx, T bean) {
ctx.getAutowireCapableBeanFactory().autowireBean(bean);
return bean;
}
In my main, I create an instance of the main application class that contains a few #Autowired annotations for the main services / entry points to my Spring application.
In an imported spring context XML file I define a bean instance that implements BeanPostProcessor.
In the importing spring context I define a number of beans (using BeanDefinitionBuilder in a custom BeanDefinitionParser).
Not all defined beans are given to the postProcessBeforeInitialization() method on my BeanPostProcessor.
It seems that some other FactoryBeans somehow affect this situation. When looking in the ApplicationContext instance with a debugger I can see all my beans inside - also the ones not being given to the BeanPostProcessor.
How can this happen?
My controller class is in com.tps.sphbIntegration.controllers package
My applicationContext.xml file is in WEB-INF/spring/applicationContext.xml
In the controller class:
#Controller
#RequestMapping("jsp")
public class SpringController {
#RequestMapping(value="register.html" , method = RequestMethod.POST)
public String enterSucess(#Valid Login login , BindingResult result , Map model,HttpSession session){
if(result.hasErrors()){
System.out.println("Error happened...");
return "register";
}else{
System.out.println("I am an controller for get method of jsp/success.html ");
login = (Login) model.get("login");
session.setAttribute("empId", login.getEmpId()) ;
session.setAttribute("empName", login.getEmpName()) ;
session.setAttribute("empPassword", login.getEmpPassword()) ;
//session.setAttribute("empGender", login.getGender()) ;
//session.setAttribute("empType", login.getEmpType()) ;
ApplicationContext factory = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
EmployeeDao dao=(EmployeeDao)factory.getBean("d");
dao.saveEmployee(login);
return "registerCheck";
}
}
}
When execution I got the exception as
java.io.FileNotFoundException: class path resource [spring/applicationContext.xml] cannot be opened because it does not exist
Please help me to set the path of applicationContext.xml in the controller or give some example that how to access the applicationContext.xml in controller.
You have to tell the servlet context loader listener where to find your Spring application context XML files in the web.xml. Your error suggests to me that you didn't do that.
If you do have it in your web.xml, check the paths to see if they're correct.
If the paths are correct, open the WAR file and see if the XML is missing. Perhaps you have a deployment and packaging issue.
A web app should NOT be calling this:
ApplicationContext factory = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
This will work if there's a spring/applicationContext.xml in your WEB-INF/classes directory, but the preferred idiom is to use the ContextLoaderListener:
Use a ContextLoaderListener in accordance with DispatchServlet
You ought to be loading the application context for your entire app on startup, not for one controller and certainly not every time this URL is called by clients. Load it once on startup.
Your controller can implement BeanFactoryAware, an interface through which it will get access to the already existing instance of the application context. You must not create the application context yourself.
It is not quite clear from your code that you really need to access the context: it looks like you need the DAO injected into your Controller, through the standard dependency-injection mechanism of Spring.
I think this is the recommend way to gain access to the applicationContext:
#Autowired
private ApplicationContext applicationContext;
Dont need to use the "*Aware" classes this way.
no no no, you can do it like this!
as will, I see there is an ANNOTATION(#Controller) in your class,that means your class has been managed by spring, if you create another Application in your method,there is two instance of ApplicationContext in memory.
let your class implement the interface of ApplicationContextAware and override the method
setApplication,and add a private member ApplicationContext, and then assign the value in that method
I am writing an application in Java and I have some REST web services there. My application has following structure: http://cl.ly/L7Pv/o
REST web service classes are Stateless session beans. It works like charm. But Classes in red on the picture want to use that REST resources too.
As fas as I know I cannot use dependency injection and annotation #EJB there. I believe I have to use JNDI lookup. Documentation: http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html
But now I dont know how to write this JNDI lookup. I have tried these two:
context.lookup("java:global/diplomka/ListResource");
context.lookup("java:global/Diplomka_maven/ListResource");
What am I doing wrong? Is this a correct approach in the first place?
Thank you
If these classes (ListResource etc.) are Stateless session beans, you can put attribute name or mappedName in #Stateless annotation, e.g.:
#Stateless(mappedName="ejb/myRestService")
public class ListResource { ..
Once you have specified JNDI name of your stateless bean, it's easy to fetch the bean through JNDI lookup:
InitialContext ic = new InitialContext();
ListResource lr = (ListResource) ic.lookup("ejb/myRestService");
lr.doWhateverNeeded(..);
As I understand it, Spring MVC application has two distinct contexts, the application context and the web context, which are controlled by applicationContext.xml and dispatcher-servlet.xml, respectively.
Inside my controllers, how do I go about loading a bean into either of these contexts?
Note that I am aware of Getting Spring Application Context. That would answer my question for a stand alone application. Where I would use a factory to load the application context from the xml file, but this seems like the wrong way to go about loading beans in Spring MVC.
Matt is absolutely correct. You should not need with any kind of bean-loading/instantiating code in your MVC application, otherwise you're doing something wrong. You define your beans inside the according spring XML configuration files.
<bean id="pinboardServiceTarget" class="com.lifepin.services.PinboardService">
<property name="pinboardEntryDao" ref="pinboardEntryDAO"/>
</bean>
...
<bean id="pinboardEntryDAO" class="com.lifepin.daos.PinboardEntryDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
Your PinboardService class (this is just from an application I wrote recently) will have a property IPinboardEntryDAO like
public class PinboardService implements IPinboardService{
private IPinboardEntryDAO pinboardEntryDao;
...
public void setPinboardEntryDAO(IPinboardEntryDAO dao){
this.pinboardEntryDao = dao;
}
public IPinboardEntryDAO getPinboardEntryDAO(){
...
}
...
}
public class PinboardEntryDAO implements IPinboardEntryDAO{
...
}
Note that inside the the PinboardService class I'm using the DAO interface, not the implementation itself, while in the configuration I'm then injecting the real implementation PinboardEntryDAO. This is a very good practice for separating the different layers (presentation, service and data layer).
Although a Spring MVC application has two distinct contexts, the web context has access to all the beans loaded in the application context. The application context however cannot access beans in the web context. This is used to enforce separation of concerns, e.g. business rules class does not need to know about the HTTP session. So if you have a bean you need access to from both contexts it will have to be declared within the application context.
Any dependencies that your Controller has (such as on service-layer classes, DAOs, etc) should be expressed as normal - through injection, either constructor injection or setter injection.
The context where the controller is mapped just wires it up with any dependencies it needs as normal. The Controller code never needs to work with Spring directly to get any beans, it is wired up with them.
You should use dependency injection and your config files to load beans into your controllers, but if you do need to access the application context directly, any Controller that extends AbstractController (or any of its descendents) has access to the getApplicationContext() method.
In stand alone application we can user context.Refresh() it will reloading/re-instantiating the new requested beans the old beans will have the old instance only.
In web applications we need to overwrite the ContextLoaderListener and call the contextInitialized()
You need to import the file containing the bean definitions of the service layer(say, service-context.xml) into the new project. It can be done as:
<import resource="classpath:service-context.xml"/>