use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.
the class BeanManagerImpl method removeUnusedBeans.
private void removeUnusedBeans() {
String excludeTypeProperty = getServices().get(WeldConfiguration.class).getStringProperty(ConfigurationKey.UNUSED_BEANS_EXCLUDE_TYPE);
if (UnusedBeans.isEnabled(excludeTypeProperty)) {
String excludeAnnotationProperty = getServices().get(WeldConfiguration.class).getStringProperty(ConfigurationKey.UNUSED_BEANS_EXCLUDE_ANNOTATION);
// Init exclude patterns
Pattern excludeAnnotation = excludeAnnotationProperty.isEmpty() ? null : Pattern.compile(excludeAnnotationProperty);
Pattern excludeType = UnusedBeans.excludeNone(excludeTypeProperty) ? null : Pattern.compile(excludeTypeProperty);
Validator validator = getServices().get(Validator.class);
// Build bean to declared producers and declared observers maps
SetMultimap<Bean<?>, AbstractProducerBean<?, ?, ?>> beanToDeclaredProducers = SetMultimap.newSetMultimap();
SetMultimap<Bean<?>, ObserverMethod<?>> beanToDeclaredObservers = SetMultimap.newSetMultimap();
for (Bean<?> bean : enabledBeans) {
if (bean instanceof AbstractProducerBean) {
AbstractProducerBean<?, ?, ?> producer = (AbstractProducerBean<?, ?, ?>) bean;
beanToDeclaredProducers.put(producer.getDeclaringBean(), producer);
}
}
for (ObserverMethod<?> observerMethod : observers) {
if (observerMethod instanceof ObserverMethodImpl) {
ObserverMethodImpl<?, ?> observerMethodImpl = (ObserverMethodImpl<?, ?>) observerMethod;
beanToDeclaredObservers.put(observerMethodImpl.getDeclaringBean(), observerMethod);
}
}
Set<Bean<?>> removable = new HashSet<>();
Set<Bean<?>> unusedProducers = new HashSet<>();
WeldUnusedMetadataExtension metadataExtension = getUnusedMetadataExtension();
for (Bean<?> bean : enabledBeans) {
bean = Beans.unwrap(bean);
// Built-in bean, extension, interceptor, decorator, session bean
if (bean instanceof AbstractBuiltInBean || bean instanceof ExtensionBean || bean instanceof Interceptor || bean instanceof Decorator || bean instanceof SessionBean) {
continue;
}
// Has a name
if (bean.getName() != null) {
continue;
}
// The type is excluded
if (excludeType != null && excludeType.matcher(bean.getBeanClass().getName()).matches()) {
continue;
}
// Declares an observer
if (beanToDeclaredObservers.containsKey(bean)) {
continue;
}
// Declares a used producer - see also second pass
if (beanToDeclaredProducers.containsKey(bean)) {
continue;
}
// Is resolved for an injection point
if (validator.isResolved(bean) || (metadataExtension != null && (metadataExtension.isInjectedByEEComponent(bean, this) || metadataExtension.isInstanceResolvedBean(bean, this)))) {
continue;
}
// The type is annotated with an exclude annotation
if (excludeAnnotation != null && hasExcludeAnnotation(bean, excludeAnnotation)) {
continue;
}
// This bean is very likely an unused producer
if (bean instanceof AbstractProducerBean) {
unusedProducers.add(bean);
}
BootstrapLogger.LOG.dropUnusedBeanMetadata(bean);
removable.add(bean);
}
// Second pass to find beans which themselves are unused and declare only unused producers
if (!unusedProducers.isEmpty()) {
for (Bean<?> bean : beanToDeclaredProducers.keySet()) {
bean = Beans.unwrap(bean);
if (!unusedProducers.containsAll(beanToDeclaredProducers.get(bean))) {
continue;
}
BootstrapLogger.LOG.dropUnusedBeanMetadata(bean);
removable.add(bean);
}
}
if (!removable.isEmpty()) {
// First remove unused beans from BeanManager
enabledBeans.removeAll(removable);
sharedBeans.removeAll(removable);
// Then perform additional cleanup
beanResolver.clear();
// Removed beans are skipped in WeldStartup.endInitialization()
cleanupBeansAfterBoot(removable);
((ContextualStoreImpl) getServices().get(ContextualStore.class)).removeAll(removable);
getServices().get(ClassTransformer.class).removeAll(removable);
}
}
}
use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.
the class ProbeObserver method notify.
@Override
public void notify(Object event) {
EventMetadata metadata = currentEventMetadata.peek();
if (excludePattern != null && excludePattern.matcher(Formats.formatType(metadata.getType(), false)).matches()) {
ProbeLogger.LOG.eventExcluded(metadata.getType());
return;
}
boolean containerEvent = isContainerEvent(metadata.getQualifiers());
List<ObserverMethod<?>> observers = resolveObservers(metadata, containerEvent);
EventInfo info = new EventInfo(metadata.getType(), metadata.getQualifiers(), event, metadata.getInjectionPoint(), observers, containerEvent, System.currentTimeMillis());
probe.addEvent(info);
}
use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.
the class ObserverNotifier method notifyAsyncObservers.
protected <T, U extends T> CompletionStage<U> notifyAsyncObservers(List<ObserverMethod<? super T>> observers, U event, EventMetadata metadata, Executor executor, NotificationOptions options) {
if (executor == null) {
executor = asyncEventExecutor;
}
if (observers.isEmpty()) {
return AsyncEventDeliveryStage.completed(event, executor);
}
// We should always initialize and validate all notification options first
final NotificationMode mode = initModeOption(options.get(WeldNotificationOptions.MODE));
final Long timeout = initTimeoutOption(options.get(WeldNotificationOptions.TIMEOUT));
final Consumer<Runnable> securityContextActionConsumer = securityServices.getSecurityContextAssociator();
// grab current TCCL
ClassLoader tccl = SecurityActions.getContextClassLoader();
final ObserverExceptionHandler exceptionHandler;
CompletableFuture<U> completableFuture;
if (observers.size() > 1 && NotificationMode.PARALLEL.equals(mode)) {
// Attempt to notify async observers in parallel
exceptionHandler = new CollectingExceptionHandler(new CopyOnWriteArrayList<>());
List<CompletableFuture<T>> completableFutures = new ArrayList<>(observers.size());
for (ObserverMethod<? super T> observer : observers) {
completableFutures.add(CompletableFuture.supplyAsync(createSupplier(tccl, securityContextActionConsumer, event, metadata, exceptionHandler, false, () -> {
notifyAsyncObserver(observer, event, metadata, exceptionHandler);
}), executor));
}
completableFuture = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[] {})).thenApply((ignoredVoid) -> {
handleExceptions(exceptionHandler);
return event;
});
} else {
// Async observers are notified serially in a single worker thread
exceptionHandler = new CollectingExceptionHandler();
completableFuture = CompletableFuture.supplyAsync(createSupplier(tccl, securityContextActionConsumer, event, metadata, exceptionHandler, true, () -> {
for (ObserverMethod<? super T> observer : observers) {
notifyAsyncObserver(observer, event, metadata, exceptionHandler);
}
}), executor);
}
// If NotificationOptionKeys.TIMEOUT is set, we will trigger the counter and use CompletableFuture.anyOf()
if (timeout != null) {
completableFuture = CompletableFuture.anyOf(completableFuture, startTimer(timeout)).thenApply((ignoredObject) -> event);
}
return new AsyncEventDeliveryStage<>(completableFuture, executor);
}
use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.
the class Probe method findUnusedBeans.
private void findUnusedBeans() {
Collection<Bean<?>> beans = idToBean.values();
Collection<ObserverMethod<?>> observers = idToObserver.values();
for (Bean<?> bean : beans) {
BeanKind kind = BeanKind.from(bean);
if (BeanKind.BUILT_IN.equals(kind) || BeanKind.EXTENSION.equals(kind) || BeanKind.DECORATOR.equals(kind) || BeanKind.INTERCEPTOR.equals(kind)) {
continue;
}
if (bean.getName() != null) {
// Is annotated with @Named
continue;
}
if (!(BeanKind.PRODUCER_FIELD.equals(kind) || BeanKind.PRODUCER_METHOD.equals(kind)) && !getDeclaredProducers(bean).isEmpty()) {
// Has declared producers
continue;
}
if (Components.hasDependents(bean, beans, this)) {
// Has direct or potential (Instance<>) dependents
continue;
}
if (hasDeclaredObserversOrIsInjectedIntoObserver(bean, observers)) {
continue;
}
if (isInjectedIntoDisposer(bean, beans)) {
continue;
}
unusedBeans.add(bean);
}
}
use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.
the class ProbeObserver method resolveObservers.
private List<ObserverMethod<?>> resolveObservers(EventMetadata metadata, boolean containerEvent) {
List<ObserverMethod<?>> observers = new ArrayList<ObserverMethod<?>>();
final ObserverNotifier notifier = (containerEvent) ? manager.getAccessibleLenientObserverNotifier() : manager.getGlobalLenientObserverNotifier();
ResolvedObservers<?> resolvedObservers = notifier.resolveObserverMethods(metadata.getType(), metadata.getQualifiers());
for (ObserverMethod<?> observer : resolvedObservers.getAllObservers()) {
// do not show ProbeObserver
if (getBeanClass() != observer.getBeanClass()) {
observers.add(observer);
}
}
return ImmutableList.copyOf(observers);
}
Aggregations