The context is the following :
An client application uses a stateless session bean in order to login on an EJB server application. If the login is successful, the client should get a stateful session bean in order to perform some transactions on his personal data. However, I would want that the login method returns a new instance of this stateful session bean such that a client should not be able to manually call this session bean and perform transactions without being authenticated. Is it possible ?
In my stateless bean I have the following code :
#Resource
private SessionContext context;
...
public StatefulBeanRemote login(username, password) {
if (ok) {
StatefulBeanRemote bean = (StatefulBeanRemote) context.lookup("StatefulBeanRemote");
return bean;
}
The lookup always fail. I don't know what I am doing wrong...
The lookup you're performing is the same as:
new InitialContext().lookup("java:comp/env/StatefulBeanRemote");
Have you defined an EJB reference to StatefulBeanRemote? Perhaps that is all you need:
#EJB(name="StatefulBeanRemote", beanInterface=StatefulBeanRemote.class)
public class MyClass {
#Resource
private SessionContext context;
...
}
Related
If I have a bean definition with some configuration within it and I use autowire to get an instance of the same class, is it the instance of the bean definition I get returned or a new instance of the class without any configurations?
class Name {
private fName;
private lName;
constructor(string fName, string lName) {
this.fName = fName;
this.lName = lName;
}
}
#Bean
public Name getName() {
Name test = new Name(thisIsMyFirstName, thisIsMyLastName);
}
--Separate File--
#Autowired
private Name testName;
Is testName here a copy of the #Bean getName() (has thisIsMyFirstName and thisIsMyLastName set) or is it a new instance of the class Name without a first name of thisIsMyFirstName and last name of thisIsMyLastName?
By default, yes, beans are singletons.
But, the Spring framework defines a number of different scopes.
singleton
Scopes a single bean definition to a single object instance per Spring IoC container.
prototype
Scopes a single bean definition to any number of object instances.
request
Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
session
Scopes a single bean definition to the lifecycle of a HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
global session
Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
The scope of a bean can be change using the #Scope annotation.
#Bean
#Scope("singleton") // <- singleton is the default. If no #Scope annotation is present, this is what is used.
public BeanA sharedBean() {
// This will only be called once, all subsequent calls will return from the cached reference in the ApplicationContext
return new BeanA();
}
#Bean
#Scope("prototype")
public BeanB privateBean() {
// This will be called every time the bean is injected and a new instance returned.
return new BeanB();
}
This is just another syntax
#Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
There is scenario where we have 50 browsers opened accessing the application , if there is a singleton scoped(meaning one bean per container), then how the singleton bean is shared among all the instance of threads
or if one object is shared to only one browser(client) then all other client will be idle waiting which is bad design
Could some body suggest answer
For stateless beans, having a single instance ("singleton") is fine:
#Component
public class MyManager {
public void doStuff();
}
Any number of clients (browsers) can call doStuff() without impacting each other as long as doStuff() doesn't manage state.
For stateful beans that manage user state, you can use session scoped beans:
#SessionScope
#Component
public class UserPreferences {
private String username;
public setUsername(String username) {
this.username = username;
}
//...
}
The UserPreferences bean is instantiated once per HTTP session. Hence every client (browser) gets its own object.
In both cases one client (browser) does not have to wait until processing has finished for other clients.
Would it be technically a good and acceptable practice to inject required dependencies using an Interceptor type. For example:
public #interface Inject {
public Class thisType();
}
public class InjectionInterceptor implements HandlerInterceptor {
#Override
public bool preHandle(HttpServletRequest hsr, HttpServletResponse hsr1, Object o) {
HandlerMethod handlerMethod = (HandlerMethod) o;
Class type = handlerMethod.getBeanType();
Annotation[] annotations = type.getAnnotationsByType(Inject.class);
for(Annotation annotation: annotations){
Inject inject = (inject) annotation;
for(Field field :type.getDeclaredFields()){
if(field.getType().equals(inject.thisType())){
field.setAccessible(true);
field.set(handlerMethod.getBean(), Services.find(inject.thisType()));
}
}
....
return true;
}
...
}
A bean can have 4 scopes.
Singleton
Only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
It is default scope of a bean.
Prototype
New instance is returned by the container when bean with the specified id is requested.
Ex: If you have a bean with id as "employee" in your spring container, then everytime you do a
Employee emp = context.getBean("employee");
A new instance will be returned.
request, session, and global session are for use only in web-based applications
Request
A new instance is created for every single HTTP request.
Ex : Login needs different instance everytime.
Session
A new instance will be created of the bean using the bean definition for the lifetime of a single HTTP Session.
global
The global session scope is similar to the standard HTTP Session scope and really only makes sense in the context of portlet-based web applications
You can specify the scope of a bean in two ways
Using XML:
<bean id="employee" class="com.company.Employee" scope="singleton"/>
Using annotation.
mark the class with #Scope("prototype")
you can read more about scopes here
sample code for reference is available here
I have the following situation: Request-scoped JAX-RS service invokes stateless EJB3 bean and the EJB3 bean retains state between successive invocation of the web service from a client.
Code as follows:
web service
#javax.enterprise.context.RequestScoped
#Path("/actions")
public class CounterFrontEnd {
#EJB
private ICounterService.ILocal counterService;
#GET #Produces("application/text;") #Path("/counter")
public String counter() {
return String.format("%d ", counterService.incCounter());
}
stateless EJB3 bean
#Stateless
#Local (ICounterService.ILocal.class)
#Remote(ICounterService.IRemote.class)
public class CounterService implements ICounterService.ILocal, ICounterService.IRemote {
public int counter = 0;
#Override
public int incCounter() {
return counter++;
}
I then invoke the service with the following python script:
for i in range(100):
os.system( 'curl http://somewhere:8080/counter-ws/rest/actions/counter' )
Surprisingly, the output is:
1 2 3 4 5 ...
This is because the container (happens) to give you the same bean-instance every time, not something you should rely on.
Stateless session-beans should not rely on instance-variables like in your example.
From java ee tutorial: http://docs.oracle.com/javaee/6/tutorial/doc/javaeetutorial6.pdf
Stateless Session Beans
A stateless session bean does not maintain a conversational state with
the client. When a client invokes the methods of a stateless bean, the
bean’s instance variables may contain a state speciic to that client
but only for the duration of the invocation. When the method is
inished, the client-speciic state should not be retained. Clients may,
however, change the state of instance variables in pooled stateless
beans, and this state is held over to the next invocation of the
pooled stateless bean. Except during method invocation, all instances
of a stateless bean are equivalent, allowing the EJB container to
assign an instance to any client. That is, the state of a stateless
session bean should apply across all clients.
As far as I know that JSF keeps all the session scoped bean in some kind of Map (correct me if I am wrong.).
In my application I have session scoped (managed by Spring and injected into the backing bean) bean named "userDetailsBean".
Is it possible to get all the instances of the bean created for different user in some sort of collection by the help of JSF API?
Add and remove them to/from some applicationwide collection/mapping yourself during #PostConstruct and #PreDestroy.
#PostConstruct
public void init() {
allSessionScopedBeans.add(this);
}
#PreDestroy
public void destroy() {
allSessionScopedBeans.remove(this);
}