Skip to content

Commit

Permalink
WELD-1970 AttributeBeanStore - lazy attribute loading
Browse files Browse the repository at this point in the history
  • Loading branch information
mkouba authored and jharting committed Aug 17, 2015
1 parent 04b5985 commit f1f1e22
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 18 deletions.
Expand Up @@ -16,8 +16,12 @@
*/
package org.jboss.weld.context.beanstore;

import static org.jboss.weld.util.reflection.Reflections.cast;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.jboss.weld.context.api.ContextualInstance;
import org.jboss.weld.logging.ContextLogger;
Expand Down Expand Up @@ -80,7 +84,7 @@ public boolean detach() {
public boolean attach() {
if (!attached) {
attached = true;
if (isLocalBeanStoreSyncNeeded()) {
if (isLocalBeanStoreSyncNeeded() && !isAttributeLazyLoadingAllowed()) {
// The local bean store is authoritative, so copy everything to the backing store
for (BeanIdentifier id : beanStore) {
ContextualInstance<?> instance = beanStore.get(id);
Expand All @@ -89,28 +93,41 @@ public boolean attach() {
setAttribute(prefixedId, instance);
}
// Additionally copy anything not in the local bean store but in the backing store
for (String prefixedId : getPrefixedAttributeNames()) {
BeanIdentifier id = getNamingScheme().deprefix(prefixedId);
if (!beanStore.contains(id)) {
ContextualInstance<?> instance = (ContextualInstance<?>) getAttribute(prefixedId);
beanStore.put(id, instance);
ContextLogger.LOG.addingDetachedContextualUnderId(instance, id);
}
}
readAttributes();
}
return true;
} else {
return false;
}
}

/**
* Read all relevant attributes from the backing store and copy instances which are not present in the local bean store.
*/
public void readAttributes() {
for (String prefixedId : getPrefixedAttributeNames()) {
BeanIdentifier id = getNamingScheme().deprefix(prefixedId);
if (!beanStore.contains(id)) {
ContextualInstance<?> instance = (ContextualInstance<?>) getAttribute(prefixedId);
beanStore.put(id, instance);
ContextLogger.LOG.addingDetachedContextualUnderId(instance, id);
}
}
}

public boolean isAttached() {
return attached;
}

@Override
public <T> ContextualInstance<T> get(BeanIdentifier id) {
ContextualInstance<T> instance = beanStore.get(id);
if(instance == null && isAttached() && isAttributeLazyLoadingAllowed()) {
instance = cast(getAttribute(namingScheme.prefix(id)));
if(instance != null) {
beanStore.put(id, instance);
}
}
ContextLogger.LOG.contextualInstanceFound(id, instance, this);
return instance;
}
Expand All @@ -119,8 +136,7 @@ public <T> ContextualInstance<T> get(BeanIdentifier id) {
public <T> void put(BeanIdentifier id, ContextualInstance<T> instance) {
beanStore.put(id, instance); // moved due to WELD-892
if (isAttached()) {
String prefixedId = namingScheme.prefix(id);
setAttribute(prefixedId, instance);
setAttribute(namingScheme.prefix(id), instance);
}
ContextLogger.LOG.contextualInstanceAdded(instance.getContextual(), id, this);
}
Expand Down Expand Up @@ -160,7 +176,21 @@ protected NamingScheme getNamingScheme() {
}

public Iterator<BeanIdentifier> iterator() {
return beanStore.iterator();
Iterator<BeanIdentifier> iterator;
if (isAttributeLazyLoadingAllowed()) {
// Merge the bean identifiers from the local bean store and the backing store
Set<BeanIdentifier> identifiers = new HashSet<>();
for (BeanIdentifier id : beanStore) {
identifiers.add(id);
}
for (String prefixedId : getPrefixedAttributeNames()) {
identifiers.add(getNamingScheme().deprefix(prefixedId));
}
iterator = identifiers.iterator();
} else {
iterator = beanStore.iterator();
}
return iterator;
}

/**
Expand Down Expand Up @@ -224,4 +254,12 @@ public LockedBean lock(final BeanIdentifier id) {
protected boolean isLocalBeanStoreSyncNeeded() {
return true;
}

/**
*
* @return <code>true</code> if attributes can be loaded lazily, <code>false</code> otherwise
*/
protected boolean isAttributeLazyLoadingAllowed() {
return false;
}
}
Expand Up @@ -32,10 +32,17 @@ public abstract class AbstractSessionBeanStore extends AttributeBeanStore {

private static final ThreadLocal<LockStore> CURRENT_LOCK_STORE = new ThreadLocal<LockStore>();

private final boolean isAttributeLazyLoadingAllowed;

protected abstract HttpSession getSession(boolean create);

public AbstractSessionBeanStore(NamingScheme namingScheme) {
this(namingScheme, true);
}

public AbstractSessionBeanStore(NamingScheme namingScheme, boolean isAttributeLazyLoadingAllowed) {
super(namingScheme);
this.isAttributeLazyLoadingAllowed = isAttributeLazyLoadingAllowed;
}

protected Iterator<String> getAttributeNames() {
Expand Down Expand Up @@ -126,4 +133,10 @@ protected LockStore getLockStore() {
}
return lockStore;
}

@Override
protected boolean isAttributeLazyLoadingAllowed() {
return isAttributeLazyLoadingAllowed;
}

}
Expand Up @@ -31,7 +31,11 @@ public class EagerSessionBeanStore extends AbstractSessionBeanStore {
private final HttpSession session;

public EagerSessionBeanStore(NamingScheme namingScheme, HttpSession session) {
super(namingScheme);
this(namingScheme, session, true);
}

public EagerSessionBeanStore(NamingScheme namingScheme, HttpSession session, boolean isAttributeLazyLoadingAllowed) {
super(namingScheme, isAttributeLazyLoadingAllowed);
this.session = session;
ContextLogger.LOG.loadingBeanStoreMapFromSession(this, getSession(false));
}
Expand Down
Expand Up @@ -48,8 +48,23 @@ public class LazySessionBeanStore extends AbstractSessionBeanStore {

private final HttpServletRequest request;

/**
*
* @param request
* @param namingScheme
*/
public LazySessionBeanStore(HttpServletRequest request, NamingScheme namingScheme) {
super(namingScheme);
this(request, namingScheme, true);
}

/**
*
* @param request
* @param namingScheme
* @param isAttributeLazyLoadingAllowed
*/
public LazySessionBeanStore(HttpServletRequest request, NamingScheme namingScheme, boolean isAttributeLazyLoadingAllowed) {
super(namingScheme, isAttributeLazyLoadingAllowed);
this.request = request;
ContextLogger.LOG.loadingBeanStoreMapFromSession(this, getSession(false));
}
Expand Down
Expand Up @@ -53,12 +53,12 @@ protected Object getRequestAttribute(HttpServletRequest request, String name) {

@Override
protected BoundBeanStore createRequestBeanStore(NamingScheme namingScheme, HttpServletRequest request) {
return new LazySessionBeanStore(request, namingScheme);
return new LazySessionBeanStore(request, namingScheme, false);
}

@Override
protected BoundBeanStore createSessionBeanStore(NamingScheme namingScheme, HttpSession session) {
return new EagerSessionBeanStore(namingScheme, session);
return new EagerSessionBeanStore(namingScheme, session, false);
}

@Override
Expand Down
Expand Up @@ -9,6 +9,8 @@

import org.jboss.weld.Container;
import org.jboss.weld.context.AbstractBoundContext;
import org.jboss.weld.context.beanstore.AttributeBeanStore;
import org.jboss.weld.context.beanstore.BoundBeanStore;
import org.jboss.weld.context.beanstore.NamingScheme;
import org.jboss.weld.context.beanstore.SimpleBeanIdentifierIndexNamingScheme;
import org.jboss.weld.context.beanstore.http.EagerSessionBeanStore;
Expand Down Expand Up @@ -44,10 +46,11 @@ public boolean associate(HttpServletRequest request) {
}

public boolean destroy(HttpSession session) {
if (getBeanStore() == null) {
final BoundBeanStore beanStore = getBeanStore();
if (beanStore == null) {
try {
HttpConversationContext conversationContext = getConversationContext();
setBeanStore(new EagerSessionBeanStore(namingScheme, session));
setBeanStore(new EagerSessionBeanStore(namingScheme, session, false));
activate();
invalidate();
conversationContext.destroy(session);
Expand All @@ -60,6 +63,10 @@ public boolean destroy(HttpSession session) {
} else {
// We are in a request, invalidate it
invalidate();
// At this moment we have to sync the local bean store and the backing store
if (beanStore instanceof AttributeBeanStore) {
((AttributeBeanStore) beanStore).readAttributes();
}
getConversationContext().destroy(session);
return false;
}
Expand Down

0 comments on commit f1f1e22

Please sign in to comment.