Skip to content

Commit

Permalink
[WELD-1001]; get bean instance on demand in proxy method handler.
Browse files Browse the repository at this point in the history
  • Loading branch information
alesj committed Nov 4, 2011
1 parent dbb8451 commit de86ca7
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 3 deletions.
@@ -0,0 +1,59 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.weld.injection;

import org.jboss.weld.bean.proxy.AbstractBeanInstance;

/**
* Create instance on demand / lazy.
*
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
*/
class OnDemandBeanInstance extends AbstractBeanInstance {
private InstanceProvider provider;
private volatile Object instance;

public OnDemandBeanInstance(InstanceProvider provider) {
this.provider = provider;
}

public Object getInstance() {
if (instance == null) {
synchronized (this) {
if (instance == null) {
instance = provider.provideInstance();
provider = null;
}
}
}
return instance;
}

public Class<?> getInstanceType() {
return getInstance().getClass();
}

static interface InstanceProvider {
Object provideInstance();
}
}
Expand Up @@ -18,8 +18,10 @@
package org.jboss.weld.injection;

import javassist.util.proxy.ProxyObject;
import org.jboss.weld.bean.DecoratorImpl;
import org.jboss.weld.bean.proxy.BeanInstance;
import org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler;
import org.jboss.weld.bean.proxy.DecoratorProxyFactory;
import org.jboss.weld.bean.proxy.ProxyFactory;
import org.jboss.weld.bean.proxy.TargetBeanInstance;
import org.jboss.weld.introspector.WeldConstructor;
import org.jboss.weld.manager.BeanManagerImpl;
Expand All @@ -37,9 +39,11 @@
* enhancing the bean instance creation process.
*
* @author <a href="mailto:mariusb@redhat.com">Marius Bogoevici</a>
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
*/
// TODO Needs equals/hashcode
// TODO Would be clearer to make this either a wrapper or not
// TODO (AJ) this needs proper cleanup!
public class ProxyClassConstructorInjectionPointWrapper<T> extends ConstructorInjectionPoint<T> {
private ConstructorInjectionPoint<T> originalConstructorInjectionPoint;
private Object decoratorDelegate = null;
Expand Down Expand Up @@ -74,9 +78,37 @@ protected Object[] getParameterValues(List<ParameterInjectionPoint<?, T>> parame
public T newInstance(BeanManagerImpl manager, CreationalContext<?> creationalContext) {
// Once the instance is created, a method handler is required regardless of whether
// an actual bean instance is known yet.
T instance = super.newInstance(manager, creationalContext);
final T instance = super.newInstance(manager, creationalContext);
if (decorator) {
DecoratorProxyFactory.setBeanInstance(instance, decoratorDelegate == null ? null : new TargetBeanInstance(decoratorDelegate), bean);
BeanInstance beanInstance = null;
if (decoratorDelegate != null) {
beanInstance = new TargetBeanInstance(decoratorDelegate);
} else if (bean instanceof DecoratorImpl) {
DecoratorImpl di = (DecoratorImpl) bean;
final WeldInjectionPoint ip = di.getDelegateInjectionPoint();
if (ip instanceof FieldInjectionPoint) {
beanInstance = new OnDemandBeanInstance(new OnDemandBeanInstance.InstanceProvider() {
public Object provideInstance() {
FieldInjectionPoint fip = (FieldInjectionPoint) ip;
return fip.delegate().get(instance);
}
});
} else if (ip instanceof MethodInjectionPoint) {
beanInstance = new OnDemandBeanInstance(new OnDemandBeanInstance.InstanceProvider() {
public Object provideInstance() {
MethodInjectionPoint mip = (MethodInjectionPoint) ip;
try {
return mip.delegate().invokeOnInstance(instance);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
} else {
throw new IllegalArgumentException("Invalid InjectionPoint: " + ip);
}
}
ProxyFactory.setBeanInstance(instance, beanInstance, bean);
} else {
if (instance instanceof ProxyObject) {
((ProxyObject) instance).setHandler(new CombinedInterceptorAndDecoratorStackMethodHandler());
Expand Down

0 comments on commit de86ca7

Please sign in to comment.