tags:

views:

268

answers:

3

Which JSF 1.2 component is responsible for instantiating managed bean specified in faces-config.xml?

I'd like to replace this component with my custom-made version which will perform some additional tasks after bean instance is successfully created.

+2  A: 

No one component is responsible for that. It is just EL which is responsible for that. If the expression #{beanname} returns null, it will create one which is associated with the managed bean name.

In your specific case, the normal way to solve this problem is just making use of the constructor of the bean or a public method of the bean annotated with @PostConstruct.

public class Bean {

    public Bean() {
        // Put code here which is to be executed during construction, but before      
        // setting of the managed properties (<managed-property> declarations).
    }

    @PostConstruct
    public void init() {
        // Put code here which is to be executed AFTER construction 
        // and the setting of managed properties.
    }

}

If you really want to take the EL resolving in your own hands, then best what you can do is to implement a custom ELResolver. You can find here an article about that.

BalusC
+1  A: 

Here is the JSP resolver structure detailed in the JSF 1.2 spec:

Faces ELResolver for JSP
|_ faces.ImplicitObjectELResolverForJSP
|_ faces.ManagedBeanELResolver
|_ faces.ResourceBundleELResolver
|_ ELResolvers in application configuration resources
|_ faces.VariableResolverChainWrapper (wraps deprecated API)
|_ faces.PropertyResolverChainWrapper (wraps deprecated API)
|_ ELResolvers from Application.addELResolver()

Managed beans will be instantiated by the faces.ManagedBeanELResolver (which is just a label developers can refer to it by, not the name of a public class).

The top-level ELResolver is provided via the Application (which you can provide via an ApplicationFactory). But, although the JSF specification details behaviour, the API does not expose the means by which the managed beans will be instantiated. It would be difficult to decorate the implementation to disambiguate between a newly instantiated bean and a bean that was returned from the request/session/application scope.

BalusC's post gives a couple of good strategies for approaching this problem.

Although JSF 2.0 brings changes to the managed bean facility, it does not, to the best of my knowledge, change this aspect of the API.

McDowell
+1  A: 

@PostConstruct is the way to go for JSF 1.2. If you are using JavaEE 6 then you can also use @Produces annotation on a method to create custom factory method.

public class CustomBeanFactory {

        @Produces
        public Bean getBean() {
           Bean bean = new Bean();
           System.out.println("Created new bean.");
           return bean;
        }

}
Raz