mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
Merge pull request #168 from lukaszlenart/initializable
WW-4849: Initializable interface Closes #165
This commit is contained in:
@@ -49,8 +49,8 @@ public class ObjectFactory implements Serializable {
|
||||
private static final Logger LOG = LogManager.getLogger(ObjectFactory.class);
|
||||
|
||||
private transient ClassLoader ccl;
|
||||
private final Container container;
|
||||
|
||||
private Container container;
|
||||
private ActionFactory actionFactory;
|
||||
private ResultFactory resultFactory;
|
||||
private InterceptorFactory interceptorFactory;
|
||||
@@ -58,8 +58,11 @@ public class ObjectFactory implements Serializable {
|
||||
private ConverterFactory converterFactory;
|
||||
private UnknownHandlerFactory unknownHandlerFactory;
|
||||
|
||||
public ObjectFactory() {
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ObjectFactory(Container container) {
|
||||
public void setContainer(Container container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2.conversion;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Initializable;
|
||||
|
||||
/**
|
||||
* Used to read converters from Properties file
|
||||
*/
|
||||
public interface ConversionPropertiesProcessor {
|
||||
public interface ConversionPropertiesProcessor extends Initializable {
|
||||
|
||||
/**
|
||||
* Process given property to load converters as not required (Properties file doesn't have to exist)
|
||||
|
||||
+7
@@ -48,6 +48,13 @@ public class DefaultConversionPropertiesProcessor implements ConversionPropertie
|
||||
this.converterHolder = converterHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
LOG.debug("Processing default conversion properties files");
|
||||
processRequired("struts-default-conversion.properties");
|
||||
process("xwork-conversion.properties");
|
||||
}
|
||||
|
||||
public void process(String propsName) {
|
||||
loadConversionProperties(propsName, false);
|
||||
}
|
||||
|
||||
@@ -171,12 +171,6 @@ public class XWorkConverter extends DefaultTypeConverter {
|
||||
this.reloadingConfigs = Boolean.parseBoolean(reloadingConfigs);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setConversionPropertiesProcessor(ConversionPropertiesProcessor propertiesProcessor) {
|
||||
propertiesProcessor.processRequired("struts-default-conversion.properties");
|
||||
propertiesProcessor.process("xwork-conversion.properties");
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setConversionFileProcessor(ConversionFileProcessor fileProcessor) {
|
||||
this.fileProcessor = fileProcessor;
|
||||
|
||||
@@ -21,7 +21,12 @@
|
||||
package com.opensymphony.xwork2.inject;
|
||||
|
||||
import java.lang.reflect.Member;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@@ -42,6 +47,7 @@ public final class ContainerBuilder {
|
||||
|
||||
final Map<Key<?>, InternalFactory<?>> factories = new HashMap<>();
|
||||
final List<InternalFactory<?>> singletonFactories = new ArrayList<>();
|
||||
final List<InternalFactory<?>> initializableFactories = new ArrayList<>();
|
||||
final List<Class<?>> staticInjections = new ArrayList<>();
|
||||
boolean created;
|
||||
boolean allowDuplicates = false;
|
||||
@@ -84,20 +90,27 @@ public final class ContainerBuilder {
|
||||
final InternalFactory<? extends T> scopedFactory = scope.scopeFactory(key.getType(), key.getName(), factory);
|
||||
factories.put(key, scopedFactory);
|
||||
if (scope == Scope.SINGLETON) {
|
||||
singletonFactories.add(new InternalFactory<T>() {
|
||||
public T create(InternalContext context) {
|
||||
try {
|
||||
context.setExternalContext(ExternalContext.newInstance(null, key, context.getContainerImpl()));
|
||||
return scopedFactory.create(context);
|
||||
} finally {
|
||||
context.setExternalContext(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
singletonFactories.add(createCallableFactory(key, scopedFactory));
|
||||
}
|
||||
if (Initializable.class.isAssignableFrom(key.getType())) {
|
||||
initializableFactories.add(createCallableFactory(key, scopedFactory));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private <T> InternalFactory<T> createCallableFactory(final Key<T> key, final InternalFactory<? extends T> scopedFactory) {
|
||||
return new InternalFactory<T>() {
|
||||
public T create(InternalContext context) {
|
||||
try {
|
||||
context.setExternalContext(ExternalContext.newInstance(null, key, context.getContainerImpl()));
|
||||
return scopedFactory.create(context);
|
||||
} finally {
|
||||
context.setExternalContext(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a key isn't already mapped.
|
||||
*
|
||||
@@ -574,6 +587,16 @@ public final class ContainerBuilder {
|
||||
}
|
||||
});
|
||||
}
|
||||
container.callInContext(new ContainerImpl.ContextualCallable<Void>() {
|
||||
public Void call(InternalContext context) {
|
||||
for (InternalFactory<?> factory : initializableFactories) {
|
||||
Initializable instance = (Initializable) factory.create(context);
|
||||
instance.init();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
container.injectStatics(staticInjections);
|
||||
return container;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2006,2009 The Apache Software Foundation.
|
||||
*
|
||||
* 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 com.opensymphony.xwork2.inject;
|
||||
|
||||
/**
|
||||
* Beans marked with this interface will be always initialised
|
||||
* after the internal DI mechanism will be created.
|
||||
*
|
||||
* It should be only used internally!
|
||||
*
|
||||
* @since Struts 2.5.14
|
||||
*/
|
||||
public interface Initializable {
|
||||
|
||||
/**
|
||||
* Use this method to initialise your bean, the whole dependency graph was already built
|
||||
*/
|
||||
void init();
|
||||
|
||||
}
|
||||
@@ -61,6 +61,9 @@ public class SpringObjectFactory extends ObjectFactory implements ApplicationCon
|
||||
@Deprecated
|
||||
private boolean enableAopSupport = false;
|
||||
|
||||
public SpringObjectFactory() {
|
||||
}
|
||||
|
||||
@Inject(value="applicationContextPath",required=false)
|
||||
public void setApplicationContextPath(String ctx) {
|
||||
if (ctx != null) {
|
||||
@@ -73,11 +76,6 @@ public class SpringObjectFactory extends ObjectFactory implements ApplicationCon
|
||||
this.enableAopSupport = BooleanUtils.toBoolean(enableAopSupport);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public SpringObjectFactory(Container container) {
|
||||
super(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Spring ApplicationContext that should be used to look beans up with.
|
||||
*
|
||||
|
||||
@@ -23,9 +23,6 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -41,9 +38,7 @@ public class SpringProxyableObjectFactory extends SpringObjectFactory {
|
||||
|
||||
private List<String> skipBeanNames = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
public SpringProxyableObjectFactory(Container container) {
|
||||
super(container);
|
||||
public SpringProxyableObjectFactory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -106,7 +106,8 @@ public class ActionAutowiringInterceptor extends AbstractInterceptor implements
|
||||
LOG.warn("ApplicationContext could not be found. Action classes will not be autowired.");
|
||||
} else {
|
||||
setApplicationContext(applicationContext);
|
||||
factory = new SpringObjectFactory(ActionContext.getContext().getContainer());
|
||||
factory = new SpringObjectFactory();
|
||||
factory.setContainer(ActionContext.getContext().getContainer());
|
||||
factory.setApplicationContext(getApplicationContext());
|
||||
if (autowireStrategy != null) {
|
||||
factory.setAutowireStrategy(autowireStrategy);
|
||||
|
||||
@@ -5,17 +5,12 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
|
||||
/**
|
||||
* ObjectFactory that returns a FooProxy in the buildBean if the clazz is FooAction
|
||||
*/
|
||||
public class ProxyObjectFactory extends ObjectFactory {
|
||||
|
||||
@Inject
|
||||
public ProxyObjectFactory(Container container) {
|
||||
super(container);
|
||||
public ProxyObjectFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-1
@@ -36,7 +36,9 @@ public class ScopedModelDrivenInterceptorTest extends XWorkTestCase {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
inter = new ScopedModelDrivenInterceptor();
|
||||
inter.setObjectFactory(new ProxyObjectFactory(container));
|
||||
ProxyObjectFactory factory = new ProxyObjectFactory();
|
||||
factory.setContainer(container);
|
||||
inter.setObjectFactory(factory);
|
||||
}
|
||||
|
||||
public void testResolveModel() throws Exception {
|
||||
|
||||
@@ -230,7 +230,8 @@ public class DispatcherTest extends StrutsInternalTestCase {
|
||||
String reloadConfigs = container.getInstance(String.class, XWorkConstants.RELOAD_XML_CONFIGURATION);
|
||||
mockContainer.expectAndReturn("getInstance", C.args(C.eq(String.class), C.eq(XWorkConstants.RELOAD_XML_CONFIGURATION)),
|
||||
reloadConfigs);
|
||||
final InnerDestroyableObjectFactory destroyedObjectFactory = new InnerDestroyableObjectFactory((Container) mockContainer.proxy());
|
||||
final InnerDestroyableObjectFactory destroyedObjectFactory = new InnerDestroyableObjectFactory();
|
||||
destroyedObjectFactory.setContainer((Container) mockContainer.proxy());
|
||||
mockContainer.expectAndReturn("getInstance", C.args(C.eq(ObjectFactory.class)), destroyedObjectFactory);
|
||||
|
||||
mockConfiguration.expectAndReturn("getContainer", mockContainer.proxy());
|
||||
@@ -261,7 +262,7 @@ public class DispatcherTest extends StrutsInternalTestCase {
|
||||
packageConfigs.put("test", packageConfig);
|
||||
|
||||
Mock mockContainer = new Mock(Container.class);
|
||||
mockContainer.matchAndReturn("getInstance", C.args(C.eq(ObjectFactory.class)), new ObjectFactory((Container) mockContainer.proxy()));
|
||||
mockContainer.matchAndReturn("getInstance", C.args(C.eq(ObjectFactory.class)), new ObjectFactory());
|
||||
String reloadConfigs = container.getInstance(String.class, XWorkConstants.RELOAD_XML_CONFIGURATION);
|
||||
mockContainer.expectAndReturn("getInstance", C.args(C.eq(String.class), C.eq(XWorkConstants.RELOAD_XML_CONFIGURATION)),
|
||||
reloadConfigs);
|
||||
@@ -316,8 +317,7 @@ public class DispatcherTest extends StrutsInternalTestCase {
|
||||
public static class InnerDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryDestroyable {
|
||||
public boolean destroyed = false;
|
||||
|
||||
public InnerDestroyableObjectFactory(Container container) {
|
||||
super(container);
|
||||
public InnerDestroyableObjectFactory() {
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
package org.apache.struts2.cdi;
|
||||
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -74,9 +73,7 @@ public class CdiObjectFactory extends ObjectFactory {
|
||||
|
||||
Map<Class<?>, InjectionTarget<?>> injectionTargetCache = new ConcurrentHashMap<Class<?>, InjectionTarget<?>>();
|
||||
|
||||
@Inject
|
||||
public CdiObjectFactory(Container container) {
|
||||
super(container);
|
||||
public CdiObjectFactory() {
|
||||
LOG.info("Initializing Struts2 CDI integration...");
|
||||
this.beanManager = findBeanManager();
|
||||
if (beanManager != null) {
|
||||
|
||||
@@ -27,19 +27,19 @@ public class CdiObjectFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testFindBeanManager() throws Exception {
|
||||
assertNotNull(new CdiObjectFactory(null).findBeanManager());
|
||||
assertNotNull(new CdiObjectFactory().findBeanManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBean() throws Exception {
|
||||
final CdiObjectFactory cdiObjectFactory = new CdiObjectFactory(null);
|
||||
final CdiObjectFactory cdiObjectFactory = new CdiObjectFactory();
|
||||
FooConsumer fooConsumer = (FooConsumer) cdiObjectFactory.buildBean(FooConsumer.class.getCanonicalName(), null, false);
|
||||
assertNotNull(fooConsumer);
|
||||
assertNotNull(fooConsumer.fooService);
|
||||
}
|
||||
|
||||
@Test public void testGetInjectionTarget() throws Exception {
|
||||
final CdiObjectFactory cdiObjectFactory = new CdiObjectFactory(null);
|
||||
final CdiObjectFactory cdiObjectFactory = new CdiObjectFactory();
|
||||
final InjectionTarget<?> injectionTarget = cdiObjectFactory.getInjectionTarget(FooConsumer.class);
|
||||
assertNotNull(injectionTarget);
|
||||
assertTrue(cdiObjectFactory.injectionTargetCache.containsKey(FooConsumer.class));
|
||||
|
||||
+5
-2
@@ -338,7 +338,8 @@ public class PackageBasedActionConfigBuilderTest extends TestCase {
|
||||
configuration.addPackageConfig("class-level", classLevelParentPkg);
|
||||
|
||||
ActionNameBuilder actionNameBuilder = new SEOActionNameBuilder("true", "-");
|
||||
ObjectFactory of = new ObjectFactory(mockContainer);
|
||||
ObjectFactory of = new ObjectFactory();
|
||||
of.setContainer(mockContainer);
|
||||
DefaultInterceptorMapBuilder interceptorBuilder = new DefaultInterceptorMapBuilder();
|
||||
interceptorBuilder.setConfiguration(configuration);
|
||||
|
||||
@@ -780,7 +781,9 @@ public class PackageBasedActionConfigBuilderTest extends TestCase {
|
||||
}
|
||||
T obj;
|
||||
if (type == ObjectFactory.class) {
|
||||
obj = type.getConstructor(Container.class).newInstance(this);
|
||||
obj = type.getConstructor().newInstance();
|
||||
((ObjectFactory)obj).setContainer(this);
|
||||
|
||||
OgnlReflectionProvider rp = new OgnlReflectionProvider() {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,9 +35,7 @@ public class DelegatingObjectFactory extends ObjectFactory implements ObjectFact
|
||||
private BundleAccessor bundleResourceLoader;
|
||||
private OsgiConfigurationProvider osgiConfigurationProvider;
|
||||
|
||||
@Inject
|
||||
public DelegatingObjectFactory(Container container) {
|
||||
super(container);
|
||||
public DelegatingObjectFactory() {
|
||||
}
|
||||
|
||||
@Inject
|
||||
|
||||
@@ -23,7 +23,6 @@ package org.apache.struts2.osgi;
|
||||
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
@@ -39,9 +38,7 @@ public class SpringOsgiObjectFactory extends ObjectFactory {
|
||||
|
||||
private BundleAccessor bundleAccessor;
|
||||
|
||||
@Inject
|
||||
public SpringOsgiObjectFactory(Container container) {
|
||||
super(container);
|
||||
public SpringOsgiObjectFactory() {
|
||||
}
|
||||
|
||||
public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal) throws Exception {
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorConfig;
|
||||
import com.opensymphony.xwork2.config.entities.ResultConfig;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -81,9 +80,7 @@ public class PlexusObjectFactory extends ObjectFactory {
|
||||
private PlexusContainer base;
|
||||
private ReflectionProvider reflectionProvider;
|
||||
|
||||
@Inject
|
||||
public PlexusObjectFactory(Container container) {
|
||||
super(container);
|
||||
public PlexusObjectFactory() {
|
||||
}
|
||||
|
||||
@Inject
|
||||
|
||||
+4
-2
@@ -48,8 +48,12 @@ import javax.servlet.ServletContext;
|
||||
* </p>
|
||||
*/
|
||||
public class StrutsSpringObjectFactory extends SpringObjectFactory {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(StrutsSpringObjectFactory.class);
|
||||
|
||||
public StrutsSpringObjectFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the spring object factory
|
||||
* @param autoWire The type of autowiring to use
|
||||
@@ -58,7 +62,6 @@ public class StrutsSpringObjectFactory extends SpringObjectFactory {
|
||||
* @param enableAopSupport enable AOP support
|
||||
* @param servletContext The servlet context
|
||||
* @param devMode development mode
|
||||
* @param container container
|
||||
* @since 2.1.3
|
||||
*/
|
||||
@Inject
|
||||
@@ -71,7 +74,6 @@ public class StrutsSpringObjectFactory extends SpringObjectFactory {
|
||||
@Inject(StrutsConstants.STRUTS_DEVMODE) String devMode,
|
||||
@Inject Container container) {
|
||||
|
||||
super(container);
|
||||
boolean useClassCache = BooleanUtils.toBoolean(useClassCacheStr);
|
||||
LOG.info("Initializing Struts-Spring integration...");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user