Class BeanContext

java.lang.Object
com.kosdev.kos.commons.core.context.BeanContext

public class BeanContext extends Object
System component that provides a very lightweight IOC-style context. It supports "phased autowiring", which allows beans to autowire a bit at a time for controlled startup, without having to worry about circular dependencies and such. It also supports asynchronous Ready infrastructure, which allows the context to pause while beans asynchronously warm up, at which point the context can continue moving forward. It also provides autowiring support for ListenerList objects, so that any beans that implement an interface of any ListenerList property will automatically be added to the listener list, even if added after the fact.

This is unique relative to standard web-style IOC containers, as we're booting an operating system which has a lot of phased steps and asynchronous processes which need to be coordinated as part of bringing up the system, which means we need a richer set of functionality. That said, this is very compact and caters only to the specific needs of KOS.

Note: The following documentation describes phased context initialization (with a phase name) as well as full initialization (without a name). As KOS uses contexts extensively and has never needed phased initialization, the phased initialization method has been removed from the SDK to avoid confusion when working with BeanContext. The documentation remains in the event that phased initialization becomes valuable in the future.

Use this object to perform dependency injection (auto-wire) on all program objects. Typical application startup looks like the following.

 
  // Instantiate all of your program objects
  // (analogous to Spring creating all @Component, @Service, and @Controller objects)
  Foo foo = new Foo();
  Bar bar = new Bar();
  Baz baz1 = new Baz();
  Baz baz2 = new Baz();

  // Create the runtime context (analogous to Spring's application context)
  RuntimeContext ctx = new RuntimeContext();

  // Add all instantiated beans (from above) to this runtime context:
  ctx.add(foo);           // unnamed objects
  ctx.add(bar);
  ctx.add("baz1", baz1);  // named objects (because there are multiple of the same type)
  ctx.add("baz2", baz2);

  // Populate all @Autowired fields for all the beans in the context and trigger
  // Ready events in any beans that implement the Ready / ReadyListener interfaces.
  ctx.update();

  // At this point, all beans (and listeners) are created and auto-wired.
  // It is also possible to connect a bean to a context. This will autowire properties
  // in the bean and add the bean to listeners in the context without actually adding
  // the bean to the context (ie. no need for it to be discoverable):
  Board board = new Board();
  ctx.connect(board);

  // If a connected bean is disposed of before the context, it should be disconnected:
  ctx.disconnect(board);
 
 
Since:
1
Version:
9
  • Constructor Summary

    Constructors
    Constructor
    Description
    Create a context without a parent using default name.
    BeanContext(BeanContext parentContext)
    Create a context with the specified parent and default name.
    Create a context without a parent.
    BeanContext(String name, BeanContext parentContext)
    Create a context with a parent.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    add(Object bean)
    Adds a bean to the context.
    void
    add(String name, Object bean)
    Adds a bean to the context with a name.
    void
    Connects a bean to the context.
    void
    Connects any listener interfaces implemented by the bean to listener lists in this context or any child contexts.
    void
    Connects any listener interfaces implemented by the bean to listener lists in this context or any parent contexts.
    void
    Destroy the bean context.
    void
    Disconnects a bean from the context.
    <T> T
    getBean(Class<? extends T> clazz)
    Returns a bean of the specified type from the context.
    <T> T
    getBean(Class<? extends T> clazz, boolean inherit)
    Returns a bean of the specified type from the context.
    <T> T
    getBean(String name, Class<T> clazz)
    Returns a bean with the specified name and type from the context.
    <T> T
    getBean(String name, Class<T> clazz, boolean inherit)
    Returns a bean with the specified name and type from the context.
    <T> List<T>
    getBeans(Class<T> clazz)
    Returns a set of beans of the specified type from the context.
    <T> List<T>
    getBeans(Class<T> clazz, boolean inherit)
    Returns a set of beans of the specified type from the context.
     
    void
    Set the parent context.
    void
    Updates the context without any phase.

    Methods inherited from class java.lang.Object

    equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • BeanContext

      public BeanContext()
      Create a context without a parent using default name.
      Since:
      1
    • BeanContext

      public BeanContext(String name)
      Create a context without a parent.
      Parameters:
      name - the name of the context
      Since:
      9
    • BeanContext

      public BeanContext(BeanContext parentContext)
      Create a context with the specified parent and default name.
      Parameters:
      parentContext - the parent context to inherit from
      Since:
      1
    • BeanContext

      public BeanContext(String name, BeanContext parentContext)
      Create a context with a parent.
      Parameters:
      name - the name of the context
      parentContext - the parent context to inherit from
      Since:
      9
  • Method Details

    • setParent

      public void setParent(BeanContext parent)
      Set the parent context. This can only be called if the parent is currently null as it makes no sense to move a context from one parent to another.
      Parameters:
      parent - the parent context
      Since:
      1
    • add

      public void add(Object bean)
      Adds a bean to the context. This can be done at any time, and will simply add the bean to the pending list. In order to trigger autowiring, either update() or update(phase) must be called. This allows any number of beans to be added before wiring occurs.
      Parameters:
      bean - the bean to add to the context
      Since:
      1
    • add

      public void add(String name, Object bean)
      Adds a bean to the context with a name. This can be done at any time and will simply add the bean to the pending list. In order to trigger autowiring, either update() or update(phase) must be called. This allows any number of beans to be added before triggering wiring. The name is optional, however the "qualifier" option of @Autowired references a name which ensures that the correct instance of a bean is returned when there are multiple of the same type available.
      Parameters:
      name - the optional unique name of the bean
      bean - the bean to add to the context
      Since:
      1
    • update

      public void update()
      Updates the context without any phase. Once this is called, the context can no longer use phases, as we assume the context is now fully initialized. If any fields are still in the pending list that reference an unused phase, then they will throw an exception, as the assumption is that the phase was accidentally skipped and something is missing. Any non-phase fields that cannot be resolved will also generate an exception.

      It is still possible to add more beans to the context and call update() again to wire them up. However, as mentioned above, they must all be successful or an exception is thrown.

      Since:
      1
    • destroy

      public void destroy()
      Destroy the bean context. This will release all references to the beans in the context as well as remove any listeners wired from this context to a parent context.
      Since:
      1
    • getBean

      public <T> T getBean(String name, Class<T> clazz)
      Returns a bean with the specified name and type from the context. This will walk up the context hierarchy to find a match.

      This is rarely required in real code as autowiring is generally a much easier and seamless approach to accessing a bean from the context.

      Type Parameters:
      T - the type of bean to return
      Parameters:
      name - the name of the bean to return
      clazz - the class of the bean to return
      Returns:
      the requested bean
      Since:
      1
    • getBean

      public <T> T getBean(String name, Class<T> clazz, boolean inherit)
      Returns a bean with the specified name and type from the context. The "inherit" flag can be used to prevent searching parent contexts.

      This is rarely required in real code as autowiring is generally a much easier and seamless approach to accessing a bean from the context. It is also quite rare to need control over inheritance.

      Type Parameters:
      T - the type of bean to return
      Parameters:
      name - the name of the bean to return
      clazz - the class of the bean to return
      inherit - if true, then search the parent context
      Returns:
      the requested bean
      Since:
      1
    • getBean

      public <T> T getBean(Class<? extends T> clazz)
      Returns a bean of the specified type from the context. If more than one bean is available, the first discovered bean will be returned. This will walk up the context hierarchy to find a match.

      This is rarely required in real code as autowiring is generally a much easier and seamless approach to accessing a bean from the context.

      Type Parameters:
      T - the type of bean to return
      Parameters:
      clazz - the class of the bean to return
      Returns:
      the requested bean
      Since:
      1
    • getBean

      public <T> T getBean(Class<? extends T> clazz, boolean inherit)
      Returns a bean of the specified type from the context. If more than one bean is available, the first discovered bean will be returned. The "inherit" flag can be used to prevent searching parent contexts.

      This is rarely required in real code as autowiring is generally a much easier and seamless approach to accessing a bean from the context. It is also quite rare to need control over inheritance.

      Type Parameters:
      T - the type of bean to return
      Parameters:
      clazz - the class of the bean to return
      inherit - if true, then search the parent context
      Returns:
      the requested bean
      Since:
      1
    • getBeans

      public <T> List<T> getBeans(Class<T> clazz)
      Returns a set of beans of the specified type from the context.

      This is rarely required in real code as AutowiredList and ListenerList already support automatic list population for a given class type. These classes also react to the addition and removal of child contexts and can fire callbacks on changes.

      Type Parameters:
      T - the type of beans to return
      Parameters:
      clazz - the class of the bean to return
      Returns:
      the list of requested beans
      Since:
      1
    • getBeans

      public <T> List<T> getBeans(Class<T> clazz, boolean inherit)
      Returns a set of beans of the specified type from the context. The "inherit" flag can be used to prevent searching parent contexts.

      This is rarely required in real code as AutowiredList and ListenerList already support automatic list population for a given class type. These classes also react to the addition and removal of child contexts and can fire callbacks on changes.

      Type Parameters:
      T - the type of beans to return
      Parameters:
      clazz - the class of the bean to return
      inherit - if true, then search the parent context
      Returns:
      the list of requested beans
      Since:
      1
    • connect

      public void connect(Object bean)
      Connects a bean to the context. This will resolve the autowired fields and attach the bean to any ListenerLists that line up with the interfaces provided by this bean. This does not add the bean to the context, and it will not receive any lifecycle events that context beans receive since this API will either return successful or throw an exception if there's anything that can't be autowired. This is particularly useful for dynamically created beans that want access to some stuff in the context without having to manually look everything up.
      Parameters:
      bean - the bean to connect to the context
      Since:
      1
    • connectListenersUp

      public void connectListenersUp(Object bean)
      Connects any listener interfaces implemented by the bean to listener lists in this context or any parent contexts.
      Parameters:
      bean - the bean to connect to the context
      Since:
      1
    • connectListenersDown

      public void connectListenersDown(Object bean)
      Connects any listener interfaces implemented by the bean to listener lists in this context or any child contexts.
      Parameters:
      bean - the bean to connect to the context
      Since:
      1
    • disconnect

      public void disconnect(Object bean)
      Disconnects a bean from the context. This is only for beans that have been passed to connect() and implement a listener interface. A listener is a reverse mapping, from the bean into the context, so it must be explicitly released unless the context the bean is connected is about to destroyed in which case the context will remove the listener reference during the destroy process.
      Parameters:
      bean - the bean to disconnect from the context
      Since:
      1
    • getName

      public String getName()