Page History
This article refers to components as in java objects that make up the foundation of the system and is not to be confused with "page components" in templating.
Table of Contents |
---|
Abstract
Terms
- Container, responsible for managing components.
- Component, anything that's configured in and managed by a container.
- ComponentProvider, is our container abstraction.
...
The key method provided by ComponentProvider is getComponent()
which is used to get the component for a specific type.
Code Block |
---|
public interface ComponentProvider {
T getComponentClass<T> type);
}
|
...
The module descriptor can specify components for different containers. This is done using the id
tag. You will rarely use a container other than main
. Here is how the XML is structured:
Code Block |
---|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module SYSTEM "module.dtd">
<module>
...
<components>
<id>main</id>
<configurer>
...
</configurer>
<component>
...
</component>
<type-mapping>
...
</type-mapping>
</components>
</module>
|
...
A typical component definition
Code Block |
---|
<component>
<type>info.magnolia.cms.filters.FilterManager</type>
<implementation>info.magnolia.cms.filters.FilterManagerImpl</implementation>
<scope>singleton</scope>
<lazy>true</lazy>
</component>
|
...
Component via provider
Code Block |
---|
<component>
<type>info.magnolia.cms.beans.config.ServerConfiguration</type>
<provider>info.magnolia.cms.beans.config.ServerConfiguration$InstanceFactory</provider>
<scope>singleton</scope>
</component>
|
...
Components from JCR
Code Block |
---|
<component>
<type>info.magnolia.cms.beans.config.URI2RepositoryManager</type>
<workspace>config</workspace>
<path>/server/URI2RepositoryMapping</path>
<observed>true</observed>
<scope>singleton</scope>
</component>
|
...
A type mapping is defined in the module descriptor alongside components:
Code Block |
---|
<type-mapping>
<type>info.magnolia.cms.core.AggregationState</type>
<implementation>info.magnolia.module.templatingkit.ExtendedAggregationState</implementation>
</type-mapping>
|
The ComponentProvider has a method for creating instances using these mappings:
Code Block |
---|
public interface ComponentProvider {
T newInstance(Class<T> type);
}
|
...
ComponentProvider can also take a set of additional arguments that will be used as constructor arguments in addition to those resolved using dependency injection.
Code Block |
---|
public interface ComponentProvider {
T newInstance(Class<T> type, Object... parameters);
}
|
It is also possible to pass in a list of custom parameter resolvers that will then assist in resolving the parameters to use.
Code Block |
---|
public interface ComponentProvider {
T newInstance(Class<T> type, ParameterResolver... parameters);
}
|
...
This is an example of what it used to look like:
Code Block |
---|
<properties>
<property>
<name>info.magnolia.module.templatingkit.sites.SiteManager</name>
<value>info.magnolia.module.templatingkit.sites.STKSiteManager</value>
</property>
<property>
<name>info.magnolia.cms.core.AggregationState</name>
<value>info.magnolia.module.templatingkit.ExtendedAggregationState</value>
</property>
</properties>
|
The equivalent component definition looks like this:
Code Block |
---|
<components>
<id>main</id>
<component>
<type>info.magnolia.module.templatingkit.sites.SiteManager</type>
<implementation>info.magnolia.module.templatingkit.sites.STKSiteManager</implementation>
<scope>singleton</scope>
<lazy>true</lazy>
</component>
<type-mapping>
<type>info.magnolia.cms.core.AggregationState</type>
<implementation>info.magnolia.module.templatingkit.ExtendedAggregationState</implementation>
</type-mapping>
</components>
|
In order to remain fully backwards compatible, Magnolia 4.5 will add both a component definition and a type mapping for AggregationState.
Supported
...
types of dependency injection
Magnolia uses the standardized annotations for dependency injections from JSR-330 which enable all three forms types of dependency injection:
- Constructor injection
- Setter Field injectionField
- Setter injection
This is an example of all three:
Code Block |
---|
public class RenderingEngine { @Inject // Dependencies are injected privatein TemplateRegistrythe templateRegistry;constructor @Inject public SomeComponent(ModuleManager moduleManager) { ... } // Fields are set with injected dependencies after construction @Inject private TemplateRegistry templateRegistry; // Setters are called with injected dependencies after construction @Inject public void setRendererRegistry(RendererRegistry rendererRegistry) { ... } } |
...
It is also possible to inject properties like this:
Code Block |
---|
@Inject
@Named("magnolia.develop")
private Provider<String> developmentMode;
|
...
When accessing an object in a lesser scope, inject a Provider
and call it when you need the object. For instance AggregationStateBasedRenderingContext
is scoped with @RequestScoped
. To access it the rendering engine depends on it like this:
Code Block |
---|
public class RenderingEngine {
public RenderingEngine(Provider<RenderingContext> renderingContextProvider) { ... }
}
|
...
Magnolia supports life cycle callbacks using the @PostConstruct
and @PreDestroy
annotations from JSR-250. A method with @PostConstruct
will be invoked after a component has been created and had its members injected. Likewise, @PreDestroy
will make the method invoked when the component provider is closed down. @PreDestroy
is however only called on singletons.
Component life cycle
A component has a life cycle with these steps
- Instantiation, the constructor annotated with
@Inject
is called with arguments resolved by the container or the default no-args constructor is used. - Fields annotated with
@Inject
are filled. - Methods annotated with
@Inject
are called with arguments resolved by the container. @PostConstruct
is called.- Component is in use.
@PreDestroy
is called when the container is closed down.
Google Guice integration
...
When Magnolia is shutdown it performs the same steps in reverse. First calling ModuleLifecycle.stop()
on modules, then it closes Main, then System and finally Platform.
Magnolia ComponentProvider hierarchy
Components with methods annotated with @PreDestroy
are called when the step in which they live is closed.