The core components of the shell are its plugin model, built-in commands, and converters
The plugin model is based Spring. Each plugin jar is required to
    contain the file
    META-INF/spring/spring-shell-plugin.xml. These files
    will be loaded to bootstrap a Spring
    ApplicationContext when the shell is
    started. The essential boostrapping code that looks for your contributions
    looks like this
new ClassPathXmlApplicationContext("classpath*:/META-INF/spring/spring-shell-plugin.xml");
    In the spring-shell-plugin.xml file you should
    define the command classes and any other collaborating objects that
    support the command's actions. The plugin model is depicted in the
    following diagram

Note that the current plugin model loads all plugins under the same class loader. An open JIRA issus is to provide a classloader per plugin to provide isolation.
An easy way to declare the commands is to use Spring's component
      scanning functionality. Here is an example
      spring-shell-plugin.xml that from the sample
      application.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:component-scan base-package="org.springframework.shell.samples.helloworld.commands" /> </beans>
The commands are Spring components, demarcated as such using the
      @Component annotation. For example, the shell of the
      HelloWorldCommands class from the sample
      application looks like this
@Component public class HelloWorldCommands implements CommandMarker { // use any Spring annotations for Dependency Injection or other Spring interfaces as required. // methods with @Cli annotations go here }
One the commands are registered and instantiated by the Spring
      container, they are registered with the core shell parser so that the
      @Cli annotations can be processed. The way the
      commands are identified is through the use of the
      CommandMarker interface.
The
      org.springframework.shell.core.Converter
      interface provides the contract to convert the strings that are entered
      on the command line to rich Java types passed into the arguments of
      @Cli-annotated methods.
By default converters for common types are registered. These cover primitive types (boolean, int, float...) as well as Date, Character, and File.
If you need to register any additional
      Converter instances, register them with
      the Spring container in the
      spring-shell-plugin.xml file and they will be
      picked up automatically.
There are a few built in commands. Here is a listing of their class name and functionality
EssentialCommands -
        exit and quit - to exit the
        shell.
HelpCommands - help -
        list all commands and their usage
OsCommands - the keyword for this command
        is the exclamation point, !. After the exclamation
        point you can pass in a unix/windows command string to be
        executed.
There are also a few commands that are provided by the
    AbstractShell class, these are
date - Displays the local date and
        time
script - Parses the specified resource file
        and executes its commands
system properties - Shows the shell's
        properties
version - Displays current CLI version
There are a few extension points that allow you to customize the shell. The extension points are the interfaces
BannerProvider - Specifies the
        banner text, welcome message, and version number that will be
        displayed when the shell is started
PromptProvider - Specifies the
        command prompt text, eg. "shell>" or
        "#" or "$"
HistoryFileNameProvider -
        Specifies the name of the command history file
There is a default implementation for these interfaces but you
    should create your own implementations for your own shell application. Use
    Spring's @Ordered annotation to set the priority of the
    provider. This allows your provider implementations to take precidence
    over any other implementations that maybe present on the classpath from
    other plugins. 
To make cool "ASCII art" banners the website http://patorjk.com/software/taag is quite neat!
As this is a standard Spring application you can use Spring's ApplicationContext event infrastructure to communicate across plugins.
It has shown to be useful to provide a simple form of interception
    around the invocation of a command method. This enables the command class
    to check for updates to state, such as configuration information modified
    by other plugins, before the command method is executed. The interface
    ExecutionProcess should be implemented
    instead of CommandMarker to access this
    functionality. The ExecutionProcess
    interface is shown below
public interface ExecutionProcessor extends CommandMarker { /** * Method called before invoking the target command (described by {@link ParseResult}). * Additionally, for advanced cases, the parse result itself effectively changing the invocation * calling site. * * @param invocationContext target command context * @return the invocation target */ ParseResult beforeInvocation(ParseResult invocationContext); /** * Method called after successfully invoking the target command (described by {@link ParseResult}). * * @param invocationContext target command context * @param result the invocation result */ void afterReturningInvocation(ParseResult invocationContext, Object result); /** * Method called after invoking the target command (described by {@link ParseResult}) had thrown an exception . * * @param invocationContext target command context * @param thrown the thrown object */ void afterThrowingInvocation(ParseResult invocationContext, Throwable thrown); }
There are a few command line options that can be specified when starting the shell. They are
--profiles - Specifies values for the system
        property spring.profiles.active so that Spring 3.1 and greater profile
        support is enabled.
--cmdfile - Specifies a file to read that
        contains shell commands
--histsize - Specifies the maximum number of
        lines to store in the command history file. Default value is
        3000.
Scripts can be executed either by passing in the
    --cmdfile argument at startup or by executing the
    script command inside the shell. When using scripts it
    helps to add comments and this can be done using block comments that start
    and end with /* and */ or an inline
    one line command using // or ;
    characters.