001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.guice; 018 019import com.google.inject.Guice; 020import com.google.inject.ImplementedBy; 021import com.google.inject.Injector; 022import com.google.inject.Module; 023import com.google.inject.Stage; 024import org.apache.wicket.Application; 025import org.apache.wicket.Component; 026import org.apache.wicket.IBehaviorInstantiationListener; 027import org.apache.wicket.Session; 028import org.apache.wicket.application.IComponentInstantiationListener; 029import org.apache.wicket.behavior.Behavior; 030import org.apache.wicket.injection.IFieldValueFactory; 031import org.apache.wicket.model.Model; 032 033/** 034 * Injects field members of components and behaviors using Guice. 035 * <p> 036 * Add this to your application in its {@link Application#init()} method like so: 037 * 038 * <pre> 039 * getComponentInstantiationListeners().add(new GuiceComponentInjector(this)); 040 * </pre> 041 * 042 * <p> 043 * There are different constructors for this object depending on how you want to wire things. See 044 * the javadoc for the constructors for more information. 045 * </p> 046 * <p> 047 * Only Wicket {@link Component}s and {@link Behavior}s are automatically injected, other classes 048 * such as {@link Session}, {@link Model}, and any other POJO can be injected by calling 049 * <code>Injector.get().inject(this)</code> in their constructor. 050 * </p> 051 * 052 * @author Alastair Maw 053 */ 054public class GuiceComponentInjector extends org.apache.wicket.injection.Injector 055 implements 056 IComponentInstantiationListener, 057 IBehaviorInstantiationListener 058{ 059 private final IFieldValueFactory fieldValueFactory; 060 061 /** 062 * Creates a new Wicket GuiceComponentInjector instance. 063 * <p> 064 * Internally this will create a new Guice {@link Injector} instance, with no {@link Module} 065 * instances. This is only useful if your beans have appropriate {@link ImplementedBy} 066 * annotations on them so that they can be automatically picked up with no extra configuration 067 * code. 068 * 069 * @param app 070 */ 071 public GuiceComponentInjector(final Application app) 072 { 073 this(app, new Module[0]); 074 } 075 076 /** 077 * Creates a new Wicket GuiceComponentInjector instance, using the supplied Guice {@link Module} 078 * instances to create a new Guice {@link Injector} instance internally. 079 * 080 * @param app 081 * @param modules 082 */ 083 public GuiceComponentInjector(final Application app, final Module... modules) 084 { 085 this(app, Guice.createInjector(app.usesDeploymentConfig() ? Stage.PRODUCTION 086 : Stage.DEVELOPMENT, modules), true); 087 } 088 089 /** 090 * Constructor 091 * 092 * @param app 093 * @param injector 094 */ 095 public GuiceComponentInjector(final Application app, final Injector injector) 096 { 097 this(app, injector, true); 098 } 099 100 /** 101 * Creates a new Wicket GuiceComponentInjector instance, using the provided Guice 102 * {@link Injector} instance. 103 * 104 * @param app 105 * @param injector 106 * @param wrapInProxies 107 * whether or not wicket should wrap dependencies with specialized proxies that can 108 * be safely serialized. in most cases this should be set to true. 109 */ 110 public GuiceComponentInjector(final Application app, final Injector injector, 111 final boolean wrapInProxies) 112 { 113 app.setMetaData(GuiceInjectorHolder.INJECTOR_KEY, new GuiceInjectorHolder(injector)); 114 fieldValueFactory = new GuiceFieldValueFactory(wrapInProxies); 115 app.getBehaviorInstantiationListeners().add(this); 116 bind(app); 117 } 118 119 @Override 120 public void inject(final Object object) 121 { 122 inject(object, fieldValueFactory); 123 } 124 125 @Override 126 public void onInstantiation(final Component component) 127 { 128 inject(component); 129 } 130 131 @Override 132 public void onInstantiation(Behavior behavior) 133 { 134 inject(behavior); 135 } 136}