| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.wicket.spring.injection.annot; |
| |
| import jakarta.servlet.ServletContext; |
| |
| import org.apache.wicket.Application; |
| import org.apache.wicket.Component; |
| import org.apache.wicket.IBehaviorInstantiationListener; |
| import org.apache.wicket.MetaDataKey; |
| import org.apache.wicket.Session; |
| import org.apache.wicket.application.IComponentInstantiationListener; |
| import org.apache.wicket.behavior.Behavior; |
| import org.apache.wicket.injection.IFieldValueFactory; |
| import org.apache.wicket.injection.Injector; |
| import org.apache.wicket.model.Model; |
| import org.apache.wicket.protocol.http.WebApplication; |
| import org.apache.wicket.spring.ISpringContextLocator; |
| import org.apache.wicket.util.lang.Args; |
| import org.springframework.context.ApplicationContext; |
| import org.springframework.web.context.support.WebApplicationContextUtils; |
| |
| /** |
| * {@link IComponentInstantiationListener} that injects component and behavior properties |
| * annotated with {@link SpringBean} annotations. |
| * |
| * To install in yourapplication.init() call |
| * <code>getComponentInstantiationListeners().add(new SpringComponentInjector(this));</code> |
| * <p> |
| * Only Wicket {@link Component}s and {@link Behavior}s are automatically injected, other classes |
| * such as {@link Session}, {@link Model}, and any other POJO can be injected by calling |
| * <code>Injector.get().inject(this)</code> in their constructor. |
| * </p> |
| * |
| * @author Igor Vaynberg (ivaynberg) |
| * @author <a href="mailto:jlee@antwerkz.com">Justin Lee</a> |
| * |
| */ |
| public class SpringComponentInjector extends Injector |
| implements |
| IComponentInstantiationListener, |
| IBehaviorInstantiationListener |
| { |
| private final IFieldValueFactory fieldValueFactory; |
| |
| /** |
| * Metadata key used to store application context in application's metadata |
| */ |
| private static MetaDataKey<ApplicationContext> CONTEXT_KEY = new MetaDataKey<>() |
| { |
| private static final long serialVersionUID = 1L; |
| |
| }; |
| |
| /** |
| * Constructor used when spring application context is declared in the spring standard way and |
| * can be located through |
| * {@link WebApplicationContextUtils#getRequiredWebApplicationContext(javax.servlet.ServletContext)}. |
| * |
| * @param webapp |
| * wicket web application |
| */ |
| public SpringComponentInjector(final WebApplication webapp) |
| { |
| this(webapp, getDefaultContext(webapp)); |
| } |
| |
| /** |
| * Constructor |
| * |
| * @param webapp |
| * wicket web application |
| * @param ctx |
| * spring's application context |
| */ |
| public SpringComponentInjector(final WebApplication webapp, final ApplicationContext ctx) |
| { |
| this(webapp, ctx, true); |
| } |
| |
| /** |
| * Constructor |
| * |
| * @param webapp |
| * wicket web application |
| * @param ctx |
| * spring's application context |
| * |
| * @param wrapInProxies |
| * whether or not wicket should wrap dependencies with specialized proxies that can |
| * be safely serialized. in most cases this should be set to true. |
| */ |
| public SpringComponentInjector(final WebApplication webapp, final ApplicationContext ctx, |
| final boolean wrapInProxies) |
| { |
| Args.notNull(webapp, "webapp"); |
| |
| Args.notNull(ctx, "ctx"); |
| |
| // store context in application's metadata ... |
| webapp.setMetaData(CONTEXT_KEY, ctx); |
| fieldValueFactory = new AnnotProxyFieldValueFactory(new ContextLocator(), wrapInProxies); |
| webapp.getBehaviorInstantiationListeners().add(this); |
| bind(webapp); |
| } |
| |
| @Override |
| public void inject(final Object object) |
| { |
| inject(object, fieldValueFactory); |
| } |
| |
| @Override |
| public void onInstantiation(final Component component) |
| { |
| inject(component); |
| } |
| |
| @Override |
| public void onInstantiation(Behavior behavior) |
| { |
| inject(behavior); |
| } |
| |
| /** |
| * A context locator that locates the context in application's metadata. This locator also keeps |
| * a transient cache of the lookup. |
| * |
| * @author ivaynberg |
| */ |
| private static class ContextLocator implements ISpringContextLocator |
| { |
| private transient ApplicationContext context; |
| |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public ApplicationContext getSpringContext() |
| { |
| if (context == null) |
| { |
| context = Application.get().getMetaData(CONTEXT_KEY); |
| } |
| return context; |
| } |
| |
| } |
| |
| /** |
| * Try to use an already pre-configured application context or locate it through Spring's default |
| * location mechanism. |
| * |
| * @param webapp |
| * @return the application context to use for injection |
| */ |
| private static ApplicationContext getDefaultContext(final WebApplication webapp) |
| { |
| ApplicationContext context = webapp.getMetaData(CONTEXT_KEY); |
| if (context == null) |
| { |
| context = WebApplicationContextUtils.getRequiredWebApplicationContext(new javax.servlet.ServletContext.Impl(webapp.getServletContext())); |
| } |
| return context; |
| } |
| |
| /** |
| * Set the default context for the given webapp. |
| * |
| * @param webapp |
| * web application |
| * @param context |
| * context to use as default if non is explicitely specified for the injector |
| */ |
| public static void setDefaultContext(final WebApplication webapp, ApplicationContext context) |
| { |
| Args.notNull(context, "context"); |
| |
| if (webapp.getMetaData(CONTEXT_KEY) == null) |
| { |
| webapp.setMetaData(CONTEXT_KEY, context); |
| } |
| } |
| } |