Jacob Orshalick (author of Seam Framework: Experience the Evolution of Java EE ) said:
Outjection allows you to make variables available from the current context for injection or access through EL. This can be beneficial if you want to loosely couple several components that inject the same context variable (like the current user, the hotel being booked, etc). If you want to avoid outjection, an alternative is to use an #Factory method or set the value directly into the context through: Contexts.getConversationContext().set("myVarName", myVar)
Another benefit is performance. By outjecting a value to the context, you can bypass having to pass through your component to get that value. This is especially applicable in the case of data tables with JSF (see this discussion). But, as you will see in the discussion you could also use #BypassInterceptors to achieve the same benefit.
Outjection is really a convenience, but the same benefits can definitely be achieved through other means. Do note that outjection was not included in Web Beans and will either be deprecated or completely removed in Seam 3, so this is further reason to avoid it when possible.
We have an application with a lot of outjections and we've started to get rid of them. He said:
but the same benefits can definitely be achieved through other means.
but which are these other means? How to remove the outjections? In ASP.NET for instance you have session variables. In Seam, you can outject var in session (a benefit in some situations).
Or page scope: (for instance in jsf cycle the backing bean is called multiple times (sometimes). You have an account which is loaded from an accountId page param. You can load the account, outject it with a page scope and you can use its properties greatly. OR (to avoid outjection) is to have a loadAccount() method where you take the account from the db whenever you need it...WORST!)
I do not think that:
Contexts.getConversationContext().set("myVarName", myVar)
is a method of how to avoid outjection.
This only calls the same context where the outjected variable is saved and modifies it in a profound way (i think it's exactly what #Out do in the background).
Question 1: What do you think guys about their intention? Do you have specific info about how they will replace it?
Question2: How do you avoid the use of outjection?
Thanks in advance.
I think the best way you can achieve "outjection" is by using #Factory. Its advantage:
It can be #In-jected into another component
It can create any value, not just component instance
It calculate the value once, and just once
It can be triggered by JSF page (I am not sure whether you must enable Seam Transaction Management in order to get this feature)
So if you have a JSF page that needs to access a #Factory more than one time, It is calculated just once. If a value needs to be calculated each time it is requested, so you need a #Unwrap method. For instance, #{currentDate} built-in component is implemented as follows
#Name("org.jboss.seam.faces.facesContext")
#Scope(ScopeType.STATELESS) // ScopeType.STATELESS is similar to Spring prototype scope
public class CurrentDate {
#Unwrap
public Date getCurrentDate() {
return new java.sql.Date(System.currentTimeMillis());
}
}
regards,
To avoid outjection just add a getter to your field in your backing bean, so instead of:
#Name("myBean")
public class MyBean{
#Out
private SomeBean someBean;
}
you will have:
#Name("myBean")
public class MyBean{
private SomeBean someBean;
public SomeBean getSomeBean(){
return someBean;
}
}
and in your xhtml/jsp file you will have to call the getter instead but this have some issues too because everytime you call the getter all the Seam Interceptors will be applied to that call so you probably will need to add #BypassInterceptors to prevent that from happening.
And yes I also think that
Contexts.getConversationContext().set("myVarName", myVar)
is just doing what outject does but manually.
Related
I am wondering if there is a pattern that forces the user of my component to set a property after it is autowired. For example i have this:
#SpringComponent
#PrototypeScope
public class MyAutowiredClass {
private String myVariabeThatTheUserShouldSet;
public MyAutowiredClass(someOtherStuff ...(not my StringVariable)){
}
}
In this example how to i force myVariabeThatTheUserShouldSet to be set from the user of this component?
Well it's a bit complicated. If it wasn't in spring context you could just add that variable to the constructor and make it "required" like that. So to achieve that in a Spring context I would advise the following:
If possible pass that value as part of the dependency injection instead of trying to work around it. I understand it is something dynamic but still usually it would have business meaning and there is a way to do it. For example if you want the current user email you can add some Service that retrieves that value and pass that service to your component and extract that value from there. Or if you want some company configuration you can add a Service that gives you that value etc. It is the "Spring" way and I would lean towards that.
A simpler solution would be to add that required field to the methods signature of the methods that actually need it. It will overload the signatures by one field but it would force the users to pass a value. If you need that field for a couple of methods and not for the correct work of the component then it would be the easiest to implement/understand solution.
Add a setter for that value and throw exception if it is not set. That would be the worse though because will require try/catches if the exception is checked and if it is not people will forget to set the field so I would avoid that solution.
I understand that for caching annotations like #Cacheable, #CachePut to work, they should be used in Spring Component class. But, I have a class that is not a Spring component or service, but I need to implement caching on one of the methods in that class.
#CachePut(cacheNames = {"NAME_OF_CACHE"})
public Object addToCache(String cacheKey) {
// Some computation here
return response;
}
I have a roadblock for converting this class to a component. Objects of this class will be initialized during runtime. Is there any way to implement this functionality?
You can manage the caching manually:
1- when you enter the function, check if the cache has the record you want and return it if yes.
2- in the end of the function insert to the cache before you return the result.
Note: you need to have an instance of your cache inside this class which is doable but not preferable.
On the other hand, if you have a problem in converting it to component because it needs to be instantiated in the runtime. Spring provides this capability, you just need to check the scope option.
You can choose the prototype scope for your purpose.
i'm new to Spring starting to learn new concepts , and i found topic speaking about bean Scopes :
- Singleton : returns the same instance every time.
- Prototype : returns new instance of the object per every request.
my question is : how is this helpful for me what is the difference between the same instance , and new instance of the object , or why the prototype scope exists !
Same instance would mean any call (from anywhere) to getBean() from ApplicationContext or BeanFactory will land you with the same instance, i.e. constructor is called just once when Spring is being initialized (per Spring container).
However, there are scenarios when you would want different object instances to work with.
For example, if you have a Point object as a member variable in a Triangle class, in case of Singleton, when the Triangle class is being instantiated, the Point object also is instantiated as it is dependent.
If you require a different instance of Point to work with elsewhere, then you will need to define the Point as a prototype, else it carries the same state.
Googling would surely help you find answers and examples demonstrating the use case.
Hope this helps.
In case if the same instance is injected everywhere as Singleton, you can use it's shared state for containing any kind of data. In case if new instance is created any time bean is being injected - it's state is not shared. By default all beans are Singletons. Prototype scope stands for cases when bean's inner data should be unique for each place you inject bean into.
Example: you have the bean which represents REST client. Different parts of application use different REST services, each requires some specific request headers - for security purposes, for example. You can inject the same REST client in all these beans to have it's own REST client bean with some specific headers. At the same time you can configure client's politics in common for the whole application - request timeouts, etc.
See also: When to use Spring prototype scope?
It helps in designing a software, refer java design patterns you fill find much useful information, In case of singleton you will be able to create only object, it will helps cases like 1.saving time in creating a very complex object (we can reuse the same object) 2.Some times we need to use the same object throughout the application E.g if you want count the total number of active users in the application, you can use singleton object to store it, because there will be only one object so you can easily update and retrieve data. In case of Prototype it will always give you different object, it is necessary in some cases like some access token, you should always get the new /valid token to proceed further, so prototype pattern /Bean is useful.
My understanding for Singleton is more likely used in the situation like return single Utility instance.
//SomeUtil is Singleton
var util = SomeUtil.getInstance();
print(util.doTask1());
print(util.doTask2());
If another thread goes into these code, SomeUtil.getInstance() just return the SomeUtil instance other than creating a new one (which might cost much to create a new one).
As to Prototype, I just found this situation using Prototype:
Lets understand this pattern using an example. I am creating an entertainment application that will require instances of Movie,
Album and Show classes very frequently. I do not want to create their instances everytime as it is costly.
So, I will create their prototype instances, and everytime when i will need a new instance,
I will just clone the prototype.
Example code locates https://github.com/keenkit/DesignPattern/tree/master/src/PrototypePattern
I found several resources to help me with this issue, but I can't seem to mix all the ingredients in order to suit my needs.
I want to "lock" a Cat (or even several) from being petted by other users, if a petting of it (or them) is already in progress. I also want to provide a feedback to the caller, telling him who called the API before him.
#Local
#Singleton // or #Stateful?
public class CatPetterBean_Local implements CatBean_Facade
{
/**
* Key - The ID of the Cat
*/
final private ConcurrentHashMap<Integer, User> pettingState = new ConcurrentHashMap<>();
#TransactionAttribute(TransactionAttributeType.REQUIRED)
#Override
public GzipROWithMsg<Object> pet(final ImmutableSet<Integer> catIds)
{
checkIfTheyAreBeingPetted_AndThrowRuntimeExec(catIds);
<...>
// After petting, they will be saved by the caller bean (e.g. CatPetterBeanImpl)
}
<...>
}
Petting takes a while
Cats retain a state in the DB: ALREADY_PETTED and NOT_PETTED. Once it is already pat, it cannot be petted again. I even thought of loading the Cat from the DB and checking its state on-the-fly, but I think it's more network traffic that way.
How can I take advantage of notions like synchronized keywords, #Lock annotations
No, I am not using Spring
No, This isn't a webapp
Yes, I do lack EE knowledge. I'm asking this question in a process of fast learning.
EJB Singletons have under the hood a locking mechanism, by default, all bean methods are serialized via write locks.
The default concurrency model on EJB Singletons is: #ConcurrencyManagement(ConcurrencyManagementType.CONTAINER), this is the default, no need to annotate the singleton with this. When Container Concurrency Management is in play as I said before every method is write locked. If you want finer control over singleton methods you can annotate them with #Lock(LockType.READ) which means that the method can be accessed concurrently while no one holds a write lock on the bean, or #Lock(LockType.WRITE) giving exclusive access to the current thread.
Alternatively, you can use Bean concurrency management. In this case, you should annotate your singleton class with: #ConcurrencyManagement(ConcurrencyManagementType.BEAN).
In this case, you use synchronized and other Java concurrency goodies. For most of my needs Container Managed concurrency was more than enough.
Another remark to the above code fragment is that #Local doesn't seem appropriate, my guess is that CatBean_Facade should be annotated with #Local.
I want to know when should I exactly use the prototype scope in Spring? I have understood that singleton returns the same object instance if the bean is requested for.
Then why should we consider prototype?
Explanations with examples would help a lot to understand the need for it.
To be clear simple definitions:
Prototype scope = A new object is created each time it is injected/looked up. It will use new SomeBean() each time.
Singleton scope = The same object is returned each time it is injected/looked up. Here it will instantiate one instance of SomeBean and then return it each time.
Prototype bean is created at the time of usage. So when you would like to have stateful beans there is a strong need sometimes to have prototypes scope or when you don't want to cache any values in beans. Prototype bean can be associated with one session or some call.
Example:
A data access object (DAO) is not typically configured as a prototype, because a typical DAO does not hold any conversational state; it was just easier for this author to reuse the core of the singleton diagram.
There are some interesting use cases by using scope prototype you will build a better and reliable application design/architecture, for example, a real-time system.
Imagine that you must build a real-time system for vehicle tracking, and you will have 2.000.000 cars sharing information every 5 seconds,
In the server side, you will work with two or more distinct group of configurations, one for Cars and another one for Trucks.
Based on this simple example, if you design your application to work with distinct configuration groups in memory through the prototype pattern you will achieve a better performance.
So, in this case, whenever the server receives a new message from a Truck, for example, the server will get the instance of the configuration in memory from a hashmap of instances of VehicleGrupConfiguration and then apply the configuration behavior that this message must have, e.g: like time-out, retry... and etc.
I would like to highlight that there are many ways to implement this situation, but this example shows that a prototype pattern is very powerful in matters of performance and design patterns.
As the documentation says, creating a bean Foo with prototype scope is same as calling:
Foo foo = new Foo(dependency1, dependency2, ...);
foo.initialize(dependency7, dependency8...);
The only good reason to use a prototype scope bean instead of new that is when the dependencies used for creation and initialization of the instance should be kept outside the code that needs a new instance.
As an example:
// need to explicitly mention dependencies here
public void createdWithNew(Dependency dependency1, Dependency dependency2) {
Foo foo = new Foo(dependency1, dependency2, ...);
foo.doSomething();
}
// Dependencies managed in class Foo by Spring
public void createdWithSpring(Foo foo) {
foo.doSomething();
}
An example is if you wanted to write persistence code similar to EJB2 Java Entity beans, such as
Person p = ...
p.setName("John Doe");
p.save(); // write to DB
Instead of using the JPA way
Person p = new Person();
p.setName("John Doe");
personService.save(p); // write to DB
In the entity bean code style, the person instance needs to know how it should be persisted, so it needs to be injected with persistence details that the code writing a person should not be aware about.
Another example:
If you want to use the non-threadsafe SimpleDateFormat Java class in many places of your application, with a format pattern from a configuration file(maybe using different formats depending on other conditions). Instead of creating a new format instance in all those places loading also the formatting string from a file (or spring property), you could use the prototype scope to get a fresh instance every time, with the details of setting the common format being in one place.