org.jboss.weld.environment.se.Weld Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.weld.environment.se;
import java.lang.annotation.Annotation;
import java.security.AccessController;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.UnsatisfiedResolutionException;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import org.jboss.weld.bootstrap.api.Bootstrap;
import org.jboss.weld.bootstrap.api.CDI11Bootstrap;
import org.jboss.weld.bootstrap.api.Environments;
import org.jboss.weld.bootstrap.api.SingletonProvider;
import org.jboss.weld.bootstrap.api.TypeDiscoveryConfiguration;
import org.jboss.weld.bootstrap.api.helpers.RegistrySingletonProvider;
import org.jboss.weld.bootstrap.spi.Deployment;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.environment.deployment.WeldBeanDeploymentArchive;
import org.jboss.weld.environment.deployment.WeldDeployment;
import org.jboss.weld.environment.deployment.WeldResourceLoader;
import org.jboss.weld.environment.deployment.discovery.DiscoveryStrategy;
import org.jboss.weld.environment.deployment.discovery.DiscoveryStrategyFactory;
import org.jboss.weld.environment.logging.CommonLogger;
import org.jboss.weld.environment.se.contexts.ThreadScoped;
import org.jboss.weld.environment.se.events.ContainerInitialized;
import org.jboss.weld.literal.InitializedLiteral;
import org.jboss.weld.metadata.MetadataImpl;
import org.jboss.weld.resources.spi.ClassFileServices;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.jboss.weld.security.GetSystemPropertyAction;
import com.google.common.collect.ImmutableSet;
/**
*
* The preferred method of booting Weld SE.
*
*
*
* Typical usage of this API looks like this:
*
*
*
* Weld weld = new Weld();
* WeldContainer container = weld.initialize();
* container.instance().select(Foo.class).get();
* container.event().select(Bar.class).fire(new Bar());
* weld.shutdown();
*
*
* @author Peter Royle
* @author Pete Muir
* @author Ales Justin
*/
public class Weld {
public static final String ARCHIVE_ISOLATION_SYSTEM_PROPERTY = "org.jboss.weld.se.archive.isolation";
private static final String BOOTSTRAP_IMPL_CLASS_NAME = "org.jboss.weld.bootstrap.WeldBootstrap";
static {
if (!(SingletonProvider.instance() instanceof RegistrySingletonProvider)) {
// make sure RegistrySingletonProvider is used (required for supporting multiple parallel Weld instances)
SingletonProvider.reset();
SingletonProvider.initialize(new RegistrySingletonProvider());
}
}
private ShutdownManager shutdownManager;
private Set> extensions;
private final String containerId;
public Weld() {
this(RegistrySingletonProvider.STATIC_INSTANCE);
}
/**
* Assign a unique ID to this Weld instance. This is required when running multiple Weld containers
* at once.
* @param containerId the unique ID for this container
*/
public Weld(String containerId) {
this.containerId = containerId;
}
/**
* Add extension explicitly.
*
* @param extension an extension
*/
public void addExtension(Extension extension) {
if (extensions == null) {
extensions = new HashSet>();
}
extensions.add(new MetadataImpl(extension, ""));
}
/**
* Boots Weld and creates and returns a WeldContainer instance, through which
* beans and events can be accessed.
*
* @return weld container
*/
public WeldContainer initialize() {
ResourceLoader resourceLoader = new WeldResourceLoader();
// check for beans.xml
if (resourceLoader.getResource(WeldDeployment.BEANS_XML) == null) {
throw CommonLogger.LOG.missingBeansXml();
}
final CDI11Bootstrap bootstrap;
try {
bootstrap = (CDI11Bootstrap) resourceLoader.classForName(BOOTSTRAP_IMPL_CLASS_NAME).newInstance();
} catch (InstantiationException ex) {
throw CommonLogger.LOG.errorLoadingWeld();
} catch (IllegalAccessException ex) {
throw CommonLogger.LOG.errorLoadingWeld();
}
Deployment deployment = createDeployment(resourceLoader, bootstrap);
// Set up the container
bootstrap.startContainer(containerId, Environments.SE, deployment);
// Start the container
bootstrap.startInitialization();
bootstrap.deployBeans();
bootstrap.validateBeans();
bootstrap.endInitialization();
final BeanManager manager = bootstrap.getManager(deployment.loadBeanDeploymentArchive(WeldContainer.class));
// Set up the ShutdownManager for later
this.shutdownManager = new ShutdownManager(bootstrap, manager);
WeldContainer container = getInstanceByType(manager, WeldContainer.class);
// notify container initialized
container.event().select(ContainerInitialized.class, InitializedLiteral.APPLICATION).fire(new ContainerInitialized());
return container;
}
private Iterable> loadExtensions(ClassLoader classLoader, Bootstrap bootstrap) {
Iterable> iter = bootstrap.loadExtensions(classLoader);
if (extensions != null) {
Set> set = new HashSet>(extensions);
for (Metadata ext : iter) {
set.add(ext);
}
return set;
} else {
return iter;
}
}
/**
*
* Extensions to Weld SE can subclass and override this method to customize the deployment before weld boots up. For example, to add a custom
* ResourceLoader, you would subclass Weld like so:
*
*
*
*
* public class MyWeld extends Weld {
* protected Deployment createDeployment(ResourceLoader resourceLoader, CDI11Bootstrap bootstrap) {
* return super.createDeployment(new MyResourceLoader(), bootstrap);
* }
* }
*
*
*
* This could then be used as normal:
*
*
*
*
* WeldContainer container = new MyWeld().initialize();
*
*
* @param resourceLoader
* @param bootstrap
*/
protected Deployment createDeployment(ResourceLoader resourceLoader, CDI11Bootstrap bootstrap) {
final Iterable> loadedExtensions = loadExtensions(WeldResourceLoader.getClassLoader(), bootstrap);
final TypeDiscoveryConfiguration typeDiscoveryConfiguration = bootstrap.startExtensions(loadedExtensions);
Deployment deployment=null;
DiscoveryStrategy strategy = DiscoveryStrategyFactory.create(
resourceLoader,
bootstrap,
ImmutableSet.> builder().addAll(typeDiscoveryConfiguration.getKnownBeanDefiningAnnotations())
// Add ThreadScoped manually as Weld SE doesn't support implicit bean archives without beans.xml
.add(ThreadScoped.class).build());
Set discoveredArchives = strategy.performDiscovery();
String isolation = AccessController.doPrivileged(new GetSystemPropertyAction(ARCHIVE_ISOLATION_SYSTEM_PROPERTY));
if (isolation != null && Boolean.valueOf(isolation).equals(Boolean.FALSE)) {
WeldBeanDeploymentArchive archive = WeldBeanDeploymentArchive.merge(bootstrap, discoveredArchives);
deployment = new WeldDeployment(resourceLoader, bootstrap, Collections.singleton(archive), loadedExtensions);
CommonLogger.LOG.archiveIsolationDisabled();
} else {
deployment= new WeldDeployment(resourceLoader, bootstrap, discoveredArchives, loadedExtensions);
CommonLogger.LOG.archiveIsolationEnabled();
}
if(strategy.getClassFileServices() != null) {
deployment.getServices().add(ClassFileServices.class, strategy.getClassFileServices());
}
return deployment;
}
/**
* Utility method allowing managed instances of beans to provide entry points for non-managed beans (such as {@link WeldContainer}). Should only called once
* Weld has finished booting.
*
* @param manager the BeanManager to use to access the managed instance
* @param type the type of the Bean
* @param bindings the bean's qualifiers
* @return a managed instance of the bean
* @throws IllegalArgumentException if the given type represents a type variable
* @throws IllegalArgumentException if two instances of the same qualifier type are given
* @throws IllegalArgumentException if an instance of an annotation that is not a qualifier type is given
* @throws UnsatisfiedResolutionException if no beans can be resolved * @throws AmbiguousResolutionException if the ambiguous dependency resolution rules
* fail
* @throws IllegalArgumentException if the given type is not a bean type of the given bean
*/
protected T getInstanceByType(BeanManager manager, Class type, Annotation... bindings) {
final Bean> bean = manager.resolve(manager.getBeans(type, bindings));
if (bean == null) {
throw CommonLogger.LOG.unableToResolveBean(type, Arrays.asList(bindings));
}
CreationalContext> cc = manager.createCreationalContext(bean);
return type.cast(manager.getReference(bean, type, cc));
}
/**
* Shuts down Weld.
*/
public void shutdown() {
if (shutdownManager != null) {
shutdownManager.shutdown();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy