Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seam outjections will be removed?

Tags:

java

jsf

seam

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.

like image 637
Cristian Boariu Avatar asked Jan 18 '10 12:01

Cristian Boariu


2 Answers

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,

like image 174
Arthur Ronald Avatar answered Sep 18 '22 22:09

Arthur Ronald


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.

like image 28
kpolice Avatar answered Sep 19 '22 22:09

kpolice