ignore

Action Bean Annotations

Many of the action bean annotations are related to dependency injection navigation. In this section we look at annotations supplied with Strecks which are also used in action beans, but are not related to dependency injection or navigation.

@Controller

The @Controller annotation is necessary for every action bean because it identifies the controller action which will execute the action bean's methods. The controller action identified using this annotation must be interface compatible with the action bean. Every controller action defines an interface which collaborating action beans must implement. The action bean which attempts to use this controller action must implement the interface.

Consider for example the following action bean:

@Controller(name = BasicController.class)
public class ExampleBasicAction implements BasicAction
{
    public String execute()
    {
        return "success";
    }
}

The action bean implements the interface BasicAction. This corresponds with the BasicController's @ActionInterface annotation, which specifies the interface that the action bean should implement, as shown below:

@ActionInterface(name = BasicAction.class)
public class BasicController extends BaseBasicController
{
    protected ViewAdapter executeAction(Object actionBean, ActionContext context)
    {
        //implementation omitted
    }
}

Summary

Location Class declaration
Purpose Identify the controller implementation class
Usage Every action bean needs to contain a @Controller annotation

@InitMethod

The @InitMethod annotation is used to indicate an action bean method which should be executed after dependencies have been injected, but before any interceptors or action bean interface methods are called. The method annotated using the @InitMethod annotation must return void and cannot define parameters. The init method can be used to perform post-dependency injection initialisation tasks. A (rather trivial) example is shown below:

@Controller(name = BasicController.class)
public class ExampleLifecycleAction implements BasicAction
{
    private static int initCount;

    @InitMethod
    public void init()
    {
        initCount++;
    }
    
    public String execute()
    {
        return "success";
    }

    public String getMessage()
    {
        return "init() called " + initCount;
    }
}

Note that in this example, the initCount field is static because the action bean is instantiated on a per-request basis. The @InitMethod annotation does not take any parameters.

@CloseMethod

The @CloseMethod annotation is the analogue of the @InitMethod annotation. It is executed after the action bean methods as well as any post-execution interceptors are called. Also, it will always be called. For example, if one of the post-execution interceptors throws an exception, this will be logged, but the subsequent close method will still be called. An example is shown below.

@Controller(name = BasicController.class)
public class ExampleLifecycleAction implements BasicAction
{
    private static int closeCount;
    
    public String execute()
    {
        return "success";
    }

    public String getMessage()
    {
        return "close() called " + closeCount;
    }
    
    @CloseMethod
    public void close()
    {
        closeCount++;
    }
}

Like @InitMethod annotation, the @CloseMethod annotation does not take any parameters.

@DispatchMethod

Struts includes a LookupDispatchAction which is useful in handling submission of forms containing multiple buttons. When using LookupDispatchAction, you need to implement an abstract getKeyMethodMap() to determine a mapping from message keys (used to name the buttons) to method names.

Streck's replacement for LookupDispatchAction is through the use of controllers which implement the LookupDispatchActionController interface. Two implementations are provided: BasicLookupDispatchController and NavigableLookupDispatchController. Action beans which use these controllers define a message key to method mapping not through an abstract method implementation, but through the use of the @DispatchMethod annotation. An example is shown below, with method implementations omitted:

@Controller(name = NavigableLookupDispatchController.class)
public class ExampleNavigableLookupSubmitAction implements NavigableSubmitAction
{
    public void preBind()
    {
    }
    
    public void execute()
    {
    }

    @DispatchMethod(key = "button.add")
    public void insert()
    {
    }

    @DispatchMethod(key = "button.delete")
    public void delete()
    {
    }

    public void cancel()
    {
    }

    @NavigateForward
    public String getResult()
    {
        return "success";
    }
}

Summary

Location Method to be executed in multi-button form
Purpose Executes request processing logic specific to one of the buttons in a multi-button form
Usage In action beans which use NavigableLookupDispatchController or BasicLookupDispatchController as action controllers

@SpringBean

Strecks provides mechanisms not only for action beans to be injected with Spring beans, but also for action beans themselves to be Spring beans. This is achieved using the @SpringBean annotation, as shown in the example below:

@Controller(name = BasicController.class)
@SpringBean(name = "springActionBean")
public class SpringControlledAction implements BasicAction
{
    private String message;

    private SpringService springService;

    public String execute()
    {
         //execute SpringService methods
    }

    public void setSpringService(SpringService service)
    {
        this.springService = service;
    }
}
Note the absence of the @InjectSpringBean annotation for setSpringService(). This is because dependency injection of Spring beans is provided by the Spring container. Note that use of Spring beans as action beans does not stop any of the Strecks annotation-based dependency injectors from being used. The Spring application context needs to be initialized using an entry such as the following in web.xml.
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-context.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

Of course, the Spring configuration file needs a bean entry corresponding with the name used in the @SpringBean annotation. The bean needs to be defined as a non-singleton (i.e. with singleton = "false")

Summary

Location Class declaration
Purpose Identify the action bean as a Spring action bean
Usage The Spring application context must be present. The action bean must be configured as a non-singleton Spring bean in the Spring application context, under the name used in the annotation
SourceForge.net logo java.net Member logo Copyright © 2005-2007 Realsolve Solutions