mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge pull request #828 from FOCONIS/feature/postconstruct
Feature/postconstruct
This commit is contained in:
@@ -167,8 +167,9 @@ public interface EbeanServer {
|
||||
/**
|
||||
* Create a new instance of T that is an EntityBean.
|
||||
* <p>
|
||||
* Generally not expected to be useful (now dynamic subclassing support was removed in
|
||||
* favour of always using enhancement).
|
||||
* Useful if you use BeanPostConstructListeners or @PostConstruct Annotations.
|
||||
* In this case you should not use "new Bean...()". Making all bean construtors protected
|
||||
* could be a good idea here.
|
||||
* </p>
|
||||
*/
|
||||
<T> T createEntityBean(Class<T> type);
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.event.BeanFindController;
|
||||
import com.avaje.ebean.event.BeanPersistController;
|
||||
import com.avaje.ebean.event.BeanPersistListener;
|
||||
import com.avaje.ebean.event.BeanPostConstructListener;
|
||||
import com.avaje.ebean.event.BeanPostLoad;
|
||||
import com.avaje.ebean.event.BeanQueryAdapter;
|
||||
import com.avaje.ebean.event.BulkTableEventListener;
|
||||
@@ -329,6 +330,7 @@ public class ServerConfig {
|
||||
private List<BeanFindController> findControllers = new ArrayList<BeanFindController>();
|
||||
private List<BeanPersistController> persistControllers = new ArrayList<BeanPersistController>();
|
||||
private List<BeanPostLoad> postLoaders = new ArrayList<BeanPostLoad>();
|
||||
private List<BeanPostConstructListener> postConstructListeners = new ArrayList<BeanPostConstructListener>();
|
||||
private List<BeanPersistListener> persistListeners = new ArrayList<BeanPersistListener>();
|
||||
private List<BeanQueryAdapter> queryAdapters = new ArrayList<BeanQueryAdapter>();
|
||||
private List<BulkTableEventListener> bulkTableEventListeners = new ArrayList<BulkTableEventListener>();
|
||||
@@ -2055,6 +2057,16 @@ public class ServerConfig {
|
||||
postLoaders.add(postLoad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a BeanPostConstructListener instance.
|
||||
* <p>
|
||||
* Note alternatively you can use {@link #setPostConstructListeners(List)} to set
|
||||
* all the BeanPostConstructListener instances.
|
||||
* </p>
|
||||
*/
|
||||
public void add(BeanPostConstructListener listener) {
|
||||
postConstructListeners.add(listener);
|
||||
}
|
||||
/**
|
||||
* Return the list of BeanFindController instances.
|
||||
*/
|
||||
@@ -2083,6 +2095,19 @@ public class ServerConfig {
|
||||
this.postLoaders = postLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of BeanPostLoader instances.
|
||||
*/
|
||||
public List<BeanPostConstructListener> getPostConstructListeners() {
|
||||
return postConstructListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of BeanPostLoader instances.
|
||||
*/
|
||||
public void setPostConstructListeners(List<BeanPostConstructListener> listeners) {
|
||||
this.postConstructListeners = listeners;
|
||||
}
|
||||
/**
|
||||
* Return the BeanPersistController instances.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.avaje.ebean.event;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
/**
|
||||
* Fired after a bean is constructed, but not yet loaded from database.
|
||||
* <p>
|
||||
* Note: You MUST NOT set any default values, as in a following step,
|
||||
* properties will get unload. Use {@link BeanPostLoad} instead.
|
||||
*
|
||||
* it's intended to do some dependency-injection here.
|
||||
* If you plan to use this feature you should use {@link EbeanServer#createEntityBean(Class)}
|
||||
* to create new beans.
|
||||
* </p>
|
||||
*/
|
||||
public interface BeanPostConstructListener {
|
||||
|
||||
/**
|
||||
* Return true if this BeanPostConstructListener instance should be registered
|
||||
* for post construct on this entity type.
|
||||
*/
|
||||
boolean isRegisterFor(Class<?> cls);
|
||||
|
||||
/**
|
||||
* Called immediately after construction. Perform DI here.
|
||||
*/
|
||||
void autowire(Object bean);
|
||||
|
||||
/**
|
||||
* Called after every @PostConstruct annotated method of the bean is executed
|
||||
*/
|
||||
void postConstruct(Object bean);
|
||||
|
||||
/**
|
||||
* Called after {@link EbeanServer#createEntityBean(Class)}. Only for new beans.
|
||||
* intended to set default values here.
|
||||
*/
|
||||
void postCreate(Object bean);
|
||||
|
||||
}
|
||||
@@ -194,6 +194,7 @@ public class DefaultContainer implements SpiContainer {
|
||||
bootup.addIdGenerators(serverConfig.getIdGenerators());
|
||||
bootup.addPersistControllers(serverConfig.getPersistControllers());
|
||||
bootup.addPostLoaders(serverConfig.getPostLoaders());
|
||||
bootup.addPostConstructListeners(serverConfig.getPostConstructListeners());
|
||||
bootup.addFindControllers(serverConfig.getFindControllers());
|
||||
bootup.addPersistListeners(serverConfig.getPersistListeners());
|
||||
bootup.addQueryAdapters(serverConfig.getQueryAdapters());
|
||||
|
||||
@@ -523,7 +523,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T createEntityBean(Class<T> type) {
|
||||
BeanDescriptor<T> desc = getBeanDescriptor(type);
|
||||
return (T) desc.createEntityBean();
|
||||
return (T) desc.createEntityBean(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.event.BeanFindController;
|
||||
import com.avaje.ebean.event.BeanPersistController;
|
||||
import com.avaje.ebean.event.BeanPersistListener;
|
||||
import com.avaje.ebean.event.BeanPostConstructListener;
|
||||
import com.avaje.ebean.event.BeanPostLoad;
|
||||
import com.avaje.ebean.event.BeanQueryAdapter;
|
||||
import com.avaje.ebean.event.ServerConfigStartup;
|
||||
@@ -41,38 +42,59 @@ public class BootupClasses implements ClassFilter {
|
||||
|
||||
private final List<Class<?>> entityList = new ArrayList<Class<?>>();
|
||||
|
||||
private final List<Class<?>> scalarTypeList = new ArrayList<Class<?>>();
|
||||
private final List<Class<? extends ScalarType<?>>> scalarTypeList
|
||||
= new ArrayList<Class<? extends ScalarType<?>>>();
|
||||
|
||||
private final List<Class<?>> scalarConverterList = new ArrayList<Class<?>>();
|
||||
private final List<Class<? extends ScalarTypeConverter<?, ?>>> scalarConverterList
|
||||
= new ArrayList<Class<? extends ScalarTypeConverter<?, ?>>>();
|
||||
|
||||
private final List<Class<?>> compoundTypeList = new ArrayList<Class<?>>();
|
||||
private final List<Class<? extends CompoundType<?>>> compoundTypeList
|
||||
= new ArrayList<Class<? extends CompoundType<?>>>();
|
||||
|
||||
private final List<Class<?>> idGeneratorList = new ArrayList<Class<?>>();
|
||||
|
||||
// The following objects are instantiiated on first request
|
||||
// there is always a candidate list, that holds the class and an
|
||||
// instance list, that holds the instance. Once a class is instantiiated
|
||||
// (or added) it will get removed from the candidate list
|
||||
private final List<Class<? extends IdGenerator>> idGeneratorCandidates
|
||||
= new ArrayList<Class<? extends IdGenerator>>();
|
||||
|
||||
private final List<Class<? extends BeanPersistController>> beanPersistControllerCandidates
|
||||
= new ArrayList<Class<? extends BeanPersistController>>();
|
||||
|
||||
private final List<Class<? extends BeanPostLoad>> beanPostLoadCandidates
|
||||
= new ArrayList<Class<? extends BeanPostLoad>>();
|
||||
|
||||
private final List<Class<?>> beanControllerList = new ArrayList<Class<?>>();
|
||||
|
||||
private final List<Class<?>> beanPostLoadList = new ArrayList<Class<?>>();
|
||||
|
||||
private final List<Class<?>> beanFindControllerList = new ArrayList<Class<?>>();
|
||||
private final List<Class<?>> beanQueryAdapterList = new ArrayList<Class<?>>();
|
||||
|
||||
private final List<Class<?>> beanListenerList = new ArrayList<Class<?>>();
|
||||
|
||||
private final List<Class<?>> serverConfigStartupList = new ArrayList<Class<?>>();
|
||||
private final List<ServerConfigStartup> serverConfigStartupInstances = new ArrayList<ServerConfigStartup>();
|
||||
private final List<Class<? extends BeanPostConstructListener>> beanPostConstructListenerCandidates
|
||||
= new ArrayList<Class<? extends BeanPostConstructListener>>();
|
||||
|
||||
private final List<Class<? extends BeanFindController>> beanFindControllerCandidates
|
||||
= new ArrayList<Class<? extends BeanFindController>>();
|
||||
|
||||
private final List<Class<? extends BeanPersistListener>> beanPersistListenerCandidates
|
||||
= new ArrayList<Class<? extends BeanPersistListener>>();
|
||||
|
||||
private final List<Class<? extends BeanQueryAdapter>> beanQueryAdapterCandidates
|
||||
= new ArrayList<Class<? extends BeanQueryAdapter>>();
|
||||
|
||||
private final List<Class<? extends ServerConfigStartup>> serverConfigStartupCandidates
|
||||
= new ArrayList<Class<? extends ServerConfigStartup>>();
|
||||
|
||||
private final List<IdGenerator> idGeneratorInstances = new ArrayList<IdGenerator>();
|
||||
private final List<BeanFindController> findControllerInstances = new ArrayList<BeanFindController>();
|
||||
private final List<BeanPersistController> persistControllerInstances = new ArrayList<BeanPersistController>();
|
||||
private final List<BeanPersistController> beanPersistControllerInstances = new ArrayList<BeanPersistController>();
|
||||
private final List<BeanPostLoad> beanPostLoadInstances = new ArrayList<BeanPostLoad>();
|
||||
private final List<BeanPersistListener> persistListenerInstances = new ArrayList<BeanPersistListener>();
|
||||
private final List<BeanQueryAdapter> queryAdapterInstances = new ArrayList<BeanQueryAdapter>();
|
||||
|
||||
private Class<?> changeLogPrepareClass;
|
||||
private Class<?> changeLogListenerClass;
|
||||
private Class<?> changeLogRegisterClass;
|
||||
private Class<?> readAuditPrepareClass;
|
||||
private Class<?> readAuditLoggerClass;
|
||||
private final List<BeanPostConstructListener> beanPostConstructListenerInstances = new ArrayList<BeanPostConstructListener>();
|
||||
private final List<BeanFindController> beanFindControllerInstances = new ArrayList<BeanFindController>();
|
||||
private final List<BeanPersistListener> beanPersistListenerInstances = new ArrayList<BeanPersistListener>();
|
||||
private final List<BeanQueryAdapter> beanQueryAdapterInstances = new ArrayList<BeanQueryAdapter>();
|
||||
private final List<ServerConfigStartup> serverConfigStartupInstances = new ArrayList<ServerConfigStartup>();
|
||||
|
||||
// single objects
|
||||
private Class<? extends ChangeLogPrepare> changeLogPrepareClass;
|
||||
private Class<? extends ChangeLogListener> changeLogListenerClass;
|
||||
private Class<? extends ChangeLogRegister> changeLogRegisterClass;
|
||||
private Class<? extends ReadAuditPrepare> readAuditPrepareClass;
|
||||
private Class<? extends ReadAuditLogger> readAuditLoggerClass;
|
||||
|
||||
private ChangeLogPrepare changeLogPrepare;
|
||||
private ChangeLogListener changeLogListener;
|
||||
@@ -96,7 +118,7 @@ public class BootupClasses implements ClassFilter {
|
||||
*/
|
||||
public void runServerConfigStartup(ServerConfig serverConfig) {
|
||||
|
||||
for (Class<?> cls : serverConfigStartupList) {
|
||||
for (Class<?> cls : serverConfigStartupCandidates) {
|
||||
try {
|
||||
ServerConfigStartup newInstance = (ServerConfigStartup) cls.newInstance();
|
||||
newInstance.onStart(serverConfig);
|
||||
@@ -115,114 +137,90 @@ public class BootupClasses implements ClassFilter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the list <code>toAdd</code> to <code>instances</code> and removes any pending
|
||||
* candiate, to prevent duplicate instantiiation.
|
||||
*/
|
||||
private <T> void add(List<T> toAdd, List<T> instances, List<Class<? extends T>> candidates) {
|
||||
if (toAdd != null) {
|
||||
for (T obj : toAdd) {
|
||||
instances.add(obj);
|
||||
// don't automatically instantiate
|
||||
candidates.remove(obj.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add IdGenerator instances (registered explicitly with the ServerConfig).
|
||||
*/
|
||||
public void addIdGenerators(List<IdGenerator> idGenerators) {
|
||||
if (idGenerators != null) {
|
||||
for (IdGenerator c : idGenerators) {
|
||||
this.idGeneratorInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.idGeneratorList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addQueryAdapters(List<BeanQueryAdapter> queryAdapterInstances) {
|
||||
if (queryAdapterInstances != null) {
|
||||
for (BeanQueryAdapter a : queryAdapterInstances) {
|
||||
this.queryAdapterInstances.add(a);
|
||||
// don't automatically instantiate
|
||||
this.beanQueryAdapterList.remove(a.getClass());
|
||||
}
|
||||
}
|
||||
add(idGenerators, idGeneratorInstances, idGeneratorCandidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BeanPersistController instances.
|
||||
*/
|
||||
public void addPersistControllers(List<BeanPersistController> beanControllerInstances) {
|
||||
if (beanControllerInstances != null) {
|
||||
for (BeanPersistController c : beanControllerInstances) {
|
||||
this.persistControllerInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.beanControllerList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
public void addPersistControllers(List<BeanPersistController> beanControllers) {
|
||||
add(beanControllers, beanPersistControllerInstances, beanPersistControllerCandidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BeanPostLoad instances.
|
||||
*/
|
||||
public void addPostLoaders(List<BeanPostLoad> postLoadInstances) {
|
||||
if (postLoadInstances != null) {
|
||||
for (BeanPostLoad c : postLoadInstances) {
|
||||
this.beanPostLoadInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.beanPostLoadList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
public void addPostLoaders(List<BeanPostLoad> postLoaders) {
|
||||
add(postLoaders, beanPostLoadInstances, beanPostLoadCandidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BeanPostConstructListener instances.
|
||||
*/
|
||||
public void addPostConstructListeners(List<BeanPostConstructListener> postConstructListener) {
|
||||
add(postConstructListener, beanPostConstructListenerInstances, beanPostConstructListenerCandidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BeanFindController instances.
|
||||
*/
|
||||
public void addFindControllers(List<BeanFindController> findControllers) {
|
||||
if (findControllers != null) {
|
||||
for (BeanFindController c : findControllers) {
|
||||
this.findControllerInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.beanFindControllerList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
add(findControllers, beanFindControllerInstances, beanFindControllerCandidates);
|
||||
}
|
||||
|
||||
public void addPersistListeners(List<BeanPersistListener> listenerInstances) {
|
||||
if (listenerInstances != null) {
|
||||
for (BeanPersistListener l : listenerInstances) {
|
||||
this.persistListenerInstances.add(l);
|
||||
// don't automatically instantiate
|
||||
this.beanListenerList.remove(l.getClass());
|
||||
}
|
||||
}
|
||||
add(listenerInstances, beanPersistListenerInstances, beanPersistListenerCandidates);
|
||||
}
|
||||
|
||||
public void addQueryAdapters(List<BeanQueryAdapter> queryAdapters) {
|
||||
add(queryAdapters, beanQueryAdapterInstances, beanQueryAdapterCandidates);
|
||||
}
|
||||
|
||||
public void addServerConfigStartup(List<ServerConfigStartup> startupInstances) {
|
||||
if (startupInstances != null) {
|
||||
for (ServerConfigStartup l : startupInstances) {
|
||||
this.serverConfigStartupInstances.add(l);
|
||||
// don't automatically instantiate
|
||||
this.serverConfigStartupList.remove(l.getClass());
|
||||
}
|
||||
}
|
||||
add(startupInstances, serverConfigStartupInstances, serverConfigStartupCandidates);
|
||||
}
|
||||
|
||||
public void addChangeLogInstances(ServerConfig serverConfig) {
|
||||
|
||||
readAuditPrepare = serverConfig.getReadAuditPrepare();
|
||||
readAuditLogger = serverConfig.getReadAuditLogger();
|
||||
|
||||
if (readAuditPrepare == null && readAuditPrepareClass != null) {
|
||||
readAuditPrepare = (ReadAuditPrepare)create(readAuditPrepareClass, false);
|
||||
}
|
||||
if (readAuditLogger == null && readAuditLoggerClass != null) {
|
||||
readAuditLogger = (ReadAuditLogger)create(readAuditLoggerClass, false);
|
||||
}
|
||||
|
||||
changeLogPrepare = serverConfig.getChangeLogPrepare();
|
||||
changeLogListener = serverConfig.getChangeLogListener();
|
||||
changeLogRegister = serverConfig.getChangeLogRegister();
|
||||
changeLogPrepare = serverConfig.getChangeLogPrepare();
|
||||
|
||||
// if not already set create the implementations found
|
||||
// via classpath scanning
|
||||
if (readAuditPrepare == null && readAuditPrepareClass != null) {
|
||||
readAuditPrepare = create(readAuditPrepareClass, false);
|
||||
}
|
||||
if (readAuditLogger == null && readAuditLoggerClass != null) {
|
||||
readAuditLogger = create(readAuditLoggerClass, false);
|
||||
}
|
||||
if (changeLogPrepare == null && changeLogPrepareClass != null) {
|
||||
changeLogPrepare = (ChangeLogPrepare)create(changeLogPrepareClass, false);
|
||||
changeLogPrepare = create(changeLogPrepareClass, false);
|
||||
}
|
||||
if (changeLogListener == null && changeLogListenerClass != null) {
|
||||
changeLogListener = (ChangeLogListener)create(changeLogListenerClass, false);
|
||||
changeLogListener = create(changeLogListenerClass, false);
|
||||
}
|
||||
if (changeLogRegister == null && changeLogRegisterClass != null) {
|
||||
changeLogRegister = (ChangeLogRegister)create(changeLogRegisterClass, false);
|
||||
changeLogRegister = create(changeLogRegisterClass, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,10 +231,10 @@ public class BootupClasses implements ClassFilter {
|
||||
* <p>
|
||||
* Use logOnException = true to log the error and carry on.
|
||||
*/
|
||||
private Object create(Class<?> cls, boolean logOnException) {
|
||||
private <T> T create(Class<T> cls, boolean logOnException) {
|
||||
try {
|
||||
// instantiate via found class
|
||||
Constructor constructor = cls.getConstructor();
|
||||
Constructor<T> constructor = cls.getConstructor();
|
||||
return constructor.newInstance();
|
||||
|
||||
} catch (NoSuchMethodException e) {
|
||||
@@ -258,13 +256,18 @@ public class BootupClasses implements ClassFilter {
|
||||
|
||||
/**
|
||||
* Create the instance if it has a default constructor and add it to the list of instances.
|
||||
* It clears the list of classes afterwards, so that each class in the given list is
|
||||
* instantiated only once
|
||||
*/
|
||||
@SuppressWarnings(value = "unchecked")
|
||||
private <T> void createAdd(Class<?> cls, List<T> instances) {
|
||||
Object newInstance = create(cls, true);
|
||||
if (newInstance != null) {
|
||||
instances.add((T)newInstance);
|
||||
}
|
||||
private <T> List<T> createAdd(List<T> instances, List<Class<? extends T>> candidates) {
|
||||
for (Class<? extends T> cls : candidates) {
|
||||
T newInstance = create(cls, true);
|
||||
if (newInstance != null) {
|
||||
instances.add(newInstance);
|
||||
}
|
||||
}
|
||||
candidates.clear(); // important, clear class list!
|
||||
return instances;
|
||||
}
|
||||
|
||||
public ChangeLogPrepare getChangeLogPrepare() {
|
||||
@@ -286,54 +289,36 @@ public class BootupClasses implements ClassFilter {
|
||||
public ReadAuditLogger getReadAuditLogger() {
|
||||
return readAuditLogger;
|
||||
}
|
||||
|
||||
public List<BeanQueryAdapter> getBeanQueryAdapters() {
|
||||
// add class registered BeanQueryAdapter to the already created instances
|
||||
for (Class<?> cls : beanQueryAdapterList) {
|
||||
createAdd(cls, queryAdapterInstances);
|
||||
}
|
||||
return queryAdapterInstances;
|
||||
|
||||
|
||||
public List<IdGenerator> getIdGenerators() {
|
||||
return createAdd(idGeneratorInstances, idGeneratorCandidates);
|
||||
}
|
||||
|
||||
public List<BeanFindController> getBeanFindControllers() {
|
||||
// add class registered BeanFindController to the list of created instances
|
||||
for (Class<?> cls : beanFindControllerList) {
|
||||
createAdd(cls, findControllerInstances);
|
||||
}
|
||||
return findControllerInstances;
|
||||
}
|
||||
|
||||
public List<BeanPersistListener> getBeanPersistListeners() {
|
||||
// add class registered BeanPersistController to the already created instances
|
||||
for (Class<?> cls : beanListenerList) {
|
||||
createAdd(cls, persistListenerInstances);
|
||||
}
|
||||
return persistListenerInstances;
|
||||
}
|
||||
|
||||
|
||||
public List<BeanPersistController> getBeanPersistControllers() {
|
||||
// add class registered BeanPersistController to the already created instances
|
||||
for (Class<?> cls : beanControllerList) {
|
||||
createAdd(cls, persistControllerInstances);
|
||||
}
|
||||
return persistControllerInstances;
|
||||
return createAdd(beanPersistControllerInstances, beanPersistControllerCandidates);
|
||||
}
|
||||
|
||||
public List<BeanPostLoad> getBeanPostLoaders() {
|
||||
// add class registered BeanPostLoad to the already created instances
|
||||
for (Class<?> cls : beanPostLoadList) {
|
||||
createAdd(cls, beanPostLoadInstances);
|
||||
}
|
||||
return beanPostLoadInstances;
|
||||
return createAdd(beanPostLoadInstances, beanPostLoadCandidates);
|
||||
}
|
||||
|
||||
public List<BeanPostConstructListener> getBeanPostConstructoListeners() {
|
||||
return createAdd(beanPostConstructListenerInstances, beanPostConstructListenerCandidates);
|
||||
}
|
||||
|
||||
public List<IdGenerator> getIdGenerators() {
|
||||
for (Class<?> cls : idGeneratorList) {
|
||||
createAdd(cls, idGeneratorInstances);
|
||||
}
|
||||
return idGeneratorInstances;
|
||||
public List<BeanFindController> getBeanFindControllers() {
|
||||
return createAdd(beanFindControllerInstances, beanFindControllerCandidates);
|
||||
}
|
||||
|
||||
|
||||
public List<BeanPersistListener> getBeanPersistListeners() {
|
||||
return createAdd(beanPersistListenerInstances, beanPersistListenerCandidates);
|
||||
}
|
||||
|
||||
public List<BeanQueryAdapter> getBeanQueryAdapters() {
|
||||
return createAdd(beanQueryAdapterInstances, beanQueryAdapterCandidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of Embeddable classes.
|
||||
*/
|
||||
@@ -351,21 +336,21 @@ public class BootupClasses implements ClassFilter {
|
||||
/**
|
||||
* Return the list of ScalarTypes found.
|
||||
*/
|
||||
public List<Class<?>> getScalarTypes() {
|
||||
public List<Class<? extends ScalarType<?>>> getScalarTypes() {
|
||||
return scalarTypeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarConverters found.
|
||||
*/
|
||||
public List<Class<?>> getScalarConverters() {
|
||||
public List<Class<? extends ScalarTypeConverter<?, ?>>> getScalarConverters() {
|
||||
return scalarConverterList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarConverters found.
|
||||
*/
|
||||
public List<Class<?>> getCompoundTypes() {
|
||||
public List<Class<? extends CompoundType<?>>> getCompoundTypes() {
|
||||
return compoundTypeList;
|
||||
}
|
||||
|
||||
@@ -391,6 +376,7 @@ public class BootupClasses implements ClassFilter {
|
||||
* This includes ScalarType, BeanController, BeanFinder and BeanListener.
|
||||
* </p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean isInterestingInterface(Class<?> cls) {
|
||||
|
||||
if (Modifier.isAbstract(cls.getModifiers())) {
|
||||
@@ -400,77 +386,87 @@ public class BootupClasses implements ClassFilter {
|
||||
}
|
||||
boolean interesting = false;
|
||||
|
||||
if (IdGenerator.class.isAssignableFrom(cls)) {
|
||||
idGeneratorList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanPersistController.class.isAssignableFrom(cls)) {
|
||||
beanControllerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanPostLoad.class.isAssignableFrom(cls)) {
|
||||
beanPostLoadList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
// Types
|
||||
if (ScalarType.class.isAssignableFrom(cls)) {
|
||||
scalarTypeList.add(cls);
|
||||
interesting = true;
|
||||
scalarTypeList.add((Class<? extends ScalarType<?>>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ScalarTypeConverter.class.isAssignableFrom(cls)) {
|
||||
scalarConverterList.add(cls);
|
||||
scalarConverterList.add((Class<? extends ScalarTypeConverter<?, ?>>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (CompoundType.class.isAssignableFrom(cls)) {
|
||||
compoundTypeList.add(cls);
|
||||
compoundTypeList.add((Class<? extends CompoundType<?>>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (IdGenerator.class.isAssignableFrom(cls)) {
|
||||
idGeneratorCandidates.add((Class<? extends IdGenerator>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
// "Candidates"
|
||||
if (BeanPersistController.class.isAssignableFrom(cls)) {
|
||||
beanPersistControllerCandidates.add((Class<? extends BeanPersistController>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanPostLoad.class.isAssignableFrom(cls)) {
|
||||
beanPostLoadCandidates.add((Class<? extends BeanPostLoad>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanPostConstructListener.class.isAssignableFrom(cls)) {
|
||||
beanPostConstructListenerCandidates.add((Class<? extends BeanPostConstructListener>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanFindController.class.isAssignableFrom(cls)) {
|
||||
beanFindControllerList.add(cls);
|
||||
beanFindControllerCandidates.add((Class<? extends BeanFindController>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (BeanPersistListener.class.isAssignableFrom(cls)) {
|
||||
beanListenerList.add(cls);
|
||||
beanPersistListenerCandidates.add((Class<? extends BeanPersistListener>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanQueryAdapter.class.isAssignableFrom(cls)) {
|
||||
beanQueryAdapterList.add(cls);
|
||||
beanQueryAdapterCandidates.add((Class<? extends BeanQueryAdapter>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ServerConfigStartup.class.isAssignableFrom(cls)) {
|
||||
serverConfigStartupList.add(cls);
|
||||
serverConfigStartupCandidates.add((Class<? extends ServerConfigStartup>) cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
// single instances
|
||||
// TODO: What should happen, if there is already an other
|
||||
// changeLogListener assigned? (Last wins? / Exception?)
|
||||
if (ChangeLogListener.class.isAssignableFrom(cls)) {
|
||||
changeLogListenerClass = cls;
|
||||
changeLogListenerClass = (Class<? extends ChangeLogListener>) cls;
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ChangeLogRegister.class.isAssignableFrom(cls)) {
|
||||
changeLogRegisterClass = cls;
|
||||
changeLogRegisterClass = (Class<? extends ChangeLogRegister>) cls;
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ChangeLogPrepare.class.isAssignableFrom(cls)) {
|
||||
changeLogPrepareClass = cls;
|
||||
changeLogPrepareClass = (Class<? extends ChangeLogPrepare>) cls;
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ReadAuditPrepare.class.isAssignableFrom(cls)) {
|
||||
readAuditPrepareClass = cls;
|
||||
readAuditPrepareClass = (Class<? extends ReadAuditPrepare>) cls;
|
||||
interesting = true;
|
||||
}
|
||||
if (ReadAuditLogger.class.isAssignableFrom(cls)) {
|
||||
readAuditLoggerClass = cls;
|
||||
readAuditLoggerClass = (Class<? extends ReadAuditLogger>) cls;
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.avaje.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
import com.avaje.ebean.event.BeanFindController;
|
||||
import com.avaje.ebean.event.BeanPersistController;
|
||||
import com.avaje.ebean.event.BeanPersistListener;
|
||||
import com.avaje.ebean.event.BeanPostConstructListener;
|
||||
import com.avaje.ebean.event.BeanPostLoad;
|
||||
import com.avaje.ebean.event.BeanQueryAdapter;
|
||||
import com.avaje.ebean.event.changelog.BeanChange;
|
||||
@@ -242,6 +243,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
private volatile BeanPersistController persistController;
|
||||
|
||||
private final BeanPostLoad beanPostLoad;
|
||||
private final BeanPostConstructListener beanPostConstructListener;
|
||||
|
||||
/**
|
||||
* Listens for post commit insert update and delete events.
|
||||
@@ -424,6 +426,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
this.beanFinder = deploy.getBeanFinder();
|
||||
this.persistController = deploy.getPersistController();
|
||||
this.persistListener = deploy.getPersistListener();
|
||||
this.beanPostConstructListener = deploy.getPostConstructListener();
|
||||
this.beanPostLoad = deploy.getPostLoad();
|
||||
this.queryAdapter = deploy.getQueryAdapter();
|
||||
this.changeLogFilter = deploy.getChangeLogFilter();
|
||||
@@ -1558,17 +1561,26 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T createBean() {
|
||||
return (T) createEntityBean();
|
||||
return (T) createEntityBean(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new EntityBean.
|
||||
* The parameter <code>isNew</code> controls either this is a new bean (then
|
||||
* {@link BeanPostConstructListener#postCreate(Object)} will be invoked) or
|
||||
* a reference (then {@link BeanPostLoad#postLoad(Object)} will be invoked
|
||||
* on first access (lazy load) or immediately (eager load)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityBean createEntityBean() {
|
||||
public EntityBean createEntityBean(boolean isNew) {
|
||||
try {
|
||||
EntityBean bean = (EntityBean) prototypeEntityBean._ebean_newInstance();
|
||||
|
||||
if (beanPostConstructListener != null) {
|
||||
beanPostConstructListener.autowire(bean); // calls all registered listeners
|
||||
beanPostConstructListener.postConstruct(bean); // calls first the @PostConstruct method and then the listeners
|
||||
}
|
||||
|
||||
if (unloadProperties.length > 0) {
|
||||
// 'unload' any properties initialised in the default constructor
|
||||
EntityBeanIntercept ebi = bean._ebean_getIntercept();
|
||||
@@ -1576,12 +1588,23 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
ebi.setPropertyUnloaded(unloadProperties[i]);
|
||||
}
|
||||
}
|
||||
if (beanPostConstructListener != null && isNew) {
|
||||
beanPostConstructListener.postCreate(bean);
|
||||
// if bean is not new, postLoad will be executed later in the bean's lifecycle
|
||||
}
|
||||
return bean;
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new PersistenceException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new entitybean without invoking {@link BeanPostConstructListener#postCreate(Object)}
|
||||
*/
|
||||
public EntityBean createEntityBean() {
|
||||
return createEntityBean(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a reference bean based on the id.
|
||||
|
||||
@@ -107,6 +107,8 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
|
||||
private final PostLoadManager postLoadManager;
|
||||
|
||||
private final PostConstructManager postConstructManager;
|
||||
|
||||
private final BeanFinderManager beanFinderManager;
|
||||
|
||||
private final PersistListenerManager persistListenerManager;
|
||||
@@ -219,6 +221,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
this.beanLifecycleAdapterFactory = new BeanLifecycleAdapterFactory();
|
||||
this.persistControllerManager = new PersistControllerManager(bootupClasses);
|
||||
this.postLoadManager = new PostLoadManager(bootupClasses);
|
||||
this.postConstructManager = new PostConstructManager(bootupClasses);
|
||||
this.persistListenerManager = new PersistListenerManager(bootupClasses);
|
||||
this.beanQueryAdapterManager = new BeanQueryAdapterManager(bootupClasses);
|
||||
this.beanFinderManager = new BeanFinderManager(bootupClasses);
|
||||
@@ -624,10 +627,11 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
int qa = beanQueryAdapterManager.getRegisterCount();
|
||||
int cc = persistControllerManager.getRegisterCount();
|
||||
int pl = postLoadManager.getRegisterCount();
|
||||
int pc = postConstructManager.getRegisterCount();
|
||||
int lc = persistListenerManager.getRegisterCount();
|
||||
int fc = beanFinderManager.getRegisterCount();
|
||||
|
||||
logger.debug("BeanPersistControllers[" + cc + "] BeanFinders[" + fc + "] BeanPersistListeners[" + lc + "] BeanQueryAdapters[" + qa + "] BeanPostLoaders[" + pl + "]");
|
||||
logger.debug("BeanPersistControllers[" + cc + "] BeanFinders[" + fc + "] BeanPersistListeners[" + lc + "] BeanQueryAdapters[" + qa + "] BeanPostLoaders[" + pl + "] BeanPostConstructors[" + pc + "]");
|
||||
}
|
||||
|
||||
private void logStatus() {
|
||||
@@ -1143,6 +1147,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
|
||||
persistControllerManager.addPersistControllers(descriptor);
|
||||
postLoadManager.addPostLoad(descriptor);
|
||||
postConstructManager.addPostConstructListeners(descriptor);
|
||||
persistListenerManager.addPersistListeners(descriptor);
|
||||
beanQueryAdapterManager.addQueryAdapter(descriptor);
|
||||
beanFinderManager.addFindControllers(descriptor);
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.PostPersist;
|
||||
@@ -16,6 +17,7 @@ import javax.persistence.PreUpdate;
|
||||
|
||||
import com.avaje.ebean.event.BeanPersistAdapter;
|
||||
import com.avaje.ebean.event.BeanPersistRequest;
|
||||
import com.avaje.ebean.event.BeanPostConstructListener;
|
||||
import com.avaje.ebean.event.BeanPostLoad;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
|
||||
@@ -50,6 +52,10 @@ public class BeanLifecycleAdapterFactory {
|
||||
// has postLoad methods
|
||||
deployDesc.addPostLoad(new PostLoadAdapter(methodHolder.postLoads));
|
||||
}
|
||||
if (!methodHolder.postConstructs.isEmpty()) {
|
||||
// has postConstruct methods
|
||||
deployDesc.addPostConstructListener(new PostConstructAdapter(methodHolder.postConstructs));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,6 +71,7 @@ public class BeanLifecycleAdapterFactory {
|
||||
private final List<Method> preDeletes = new ArrayList<Method>();
|
||||
private final List<Method> postDeletes = new ArrayList<Method>();
|
||||
private final List<Method> postLoads = new ArrayList<Method>();
|
||||
private final List<Method> postConstructs = new ArrayList<Method>();
|
||||
|
||||
/**
|
||||
* Has one of the pre or post insert update delete annotated methods.
|
||||
@@ -107,6 +114,9 @@ public class BeanLifecycleAdapterFactory {
|
||||
if (method.isAnnotationPresent(PostLoad.class)) {
|
||||
postLoads.add(method);
|
||||
}
|
||||
if (method.isAnnotationPresent(PostConstruct.class)) {
|
||||
postConstructs.add(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,4 +251,49 @@ public class BeanLifecycleAdapterFactory {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PostConstructAdapter using reflection to invoke lifecycle methods.
|
||||
*/
|
||||
private static class PostConstructAdapter implements BeanPostConstructListener {
|
||||
|
||||
private final Method[] postConstructMethods;
|
||||
|
||||
private PostConstructAdapter(List<Method> postConstructMethods) {
|
||||
this.postConstructMethods = toArray(postConstructMethods);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegisterFor(Class<?> cls) {
|
||||
// Not used
|
||||
return false;
|
||||
}
|
||||
|
||||
private void invoke(Method method, Object bean) {
|
||||
try {
|
||||
method.invoke(bean);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new PersistenceException("Error invoking lifecycle method", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new PersistenceException("Error invoking lifecycle method", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postConstruct(Object bean) {
|
||||
for (int i = 0; i < postConstructMethods.length; i++) {
|
||||
invoke(postConstructMethods[i], bean);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autowire(Object bean) {
|
||||
// autowire is done by global PostConstructListener only
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postCreate(Object bean) {
|
||||
// postCreate is done by global PostConstructListener only
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public class ChainedBeanPersistListener implements BeanPersistListener {
|
||||
private final BeanPersistListener[] chain;
|
||||
|
||||
/**
|
||||
* Construct adding 2 BeanPersistController's.
|
||||
* Construct adding 2 BeanPersistListener's.
|
||||
*/
|
||||
public ChainedBeanPersistListener(BeanPersistListener c1, BeanPersistListener c2) {
|
||||
this(addList(c1, c2));
|
||||
@@ -46,7 +46,7 @@ public class ChainedBeanPersistListener implements BeanPersistListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct given the list of BeanPersistController's.
|
||||
* Construct given the list of BeanPersistListener's.
|
||||
*/
|
||||
public ChainedBeanPersistListener(List<BeanPersistListener> list) {
|
||||
this.list = list;
|
||||
@@ -54,7 +54,7 @@ public class ChainedBeanPersistListener implements BeanPersistListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new BeanPersistController and return the resulting chain.
|
||||
* Register a new BeanPersistListener and return the resulting chain.
|
||||
*/
|
||||
public ChainedBeanPersistListener register(BeanPersistListener c) {
|
||||
if (list.contains(c)){
|
||||
@@ -69,7 +69,7 @@ public class ChainedBeanPersistListener implements BeanPersistListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* De-register a BeanPersistController and return the resulting chain.
|
||||
* De-register a BeanPersistListener and return the resulting chain.
|
||||
*/
|
||||
public ChainedBeanPersistListener deregister(BeanPersistListener c) {
|
||||
if (!list.contains(c)){
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import com.avaje.ebean.event.BeanPostConstructListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles multiple BeanPostLoad's for a given entity type.
|
||||
*/
|
||||
public class ChainedBeanPostConstructListener implements BeanPostConstructListener {
|
||||
|
||||
private final List<BeanPostConstructListener> list;
|
||||
|
||||
private final BeanPostConstructListener[] chain;
|
||||
|
||||
/**
|
||||
* Construct given the list of BeanPostCreate's.
|
||||
*/
|
||||
public ChainedBeanPostConstructListener(List<BeanPostConstructListener> list) {
|
||||
this.list = list;
|
||||
this.chain = list.toArray(new BeanPostConstructListener[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new BeanPostCreate and return the resulting chain.
|
||||
*/
|
||||
public ChainedBeanPostConstructListener register(BeanPostConstructListener c) {
|
||||
if (list.contains(c)){
|
||||
return this;
|
||||
} else {
|
||||
List<BeanPostConstructListener> newList = new ArrayList<BeanPostConstructListener>();
|
||||
newList.addAll(list);
|
||||
newList.add(c);
|
||||
|
||||
return new ChainedBeanPostConstructListener(newList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* De-register a BeanPostCreate and return the resulting chain.
|
||||
*/
|
||||
public BeanPostConstructListener deregister(BeanPostConstructListener c) {
|
||||
if (!list.contains(c)){
|
||||
return this;
|
||||
} else {
|
||||
ArrayList<BeanPostConstructListener> newList = new ArrayList<BeanPostConstructListener>();
|
||||
newList.addAll(list);
|
||||
newList.remove(c);
|
||||
|
||||
return new ChainedBeanPostConstructListener(newList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the chain.
|
||||
*/
|
||||
protected int size() {
|
||||
return chain.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegisterFor(Class<?> cls) {
|
||||
// never called
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire postLoad on all registered BeanPostCreate implementations.
|
||||
*/
|
||||
@Override
|
||||
public void postConstruct(Object bean) {
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
chain[i].postConstruct(bean);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autowire(Object bean) {
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
chain[i].autowire(bean);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postCreate(Object bean) {
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
chain[i].postCreate(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public class ChainedBeanPostLoad implements BeanPostLoad {
|
||||
private final BeanPostLoad[] chain;
|
||||
|
||||
/**
|
||||
* Construct given the list of BeanPersistController's.
|
||||
* Construct given the list of BeanPostLoad's.
|
||||
*/
|
||||
public ChainedBeanPostLoad(List<BeanPostLoad> list) {
|
||||
this.list = list;
|
||||
@@ -23,7 +23,7 @@ public class ChainedBeanPostLoad implements BeanPostLoad {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new BeanPersistController and return the resulting chain.
|
||||
* Register a new BeanPostLoad and return the resulting chain.
|
||||
*/
|
||||
public ChainedBeanPostLoad register(BeanPostLoad c) {
|
||||
if (list.contains(c)){
|
||||
@@ -38,7 +38,7 @@ public class ChainedBeanPostLoad implements BeanPostLoad {
|
||||
}
|
||||
|
||||
/**
|
||||
* De-register a BeanPersistController and return the resulting chain.
|
||||
* De-register a BeanPostLoad and return the resulting chain.
|
||||
*/
|
||||
public ChainedBeanPostLoad deregister(BeanPostLoad c) {
|
||||
if (!list.contains(c)){
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import com.avaje.ebean.event.BeanPostConstructListener;
|
||||
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default implementation for creating BeanControllers.
|
||||
*/
|
||||
public class PostConstructManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PostConstructManager.class);
|
||||
|
||||
private final List<BeanPostConstructListener> list;
|
||||
|
||||
public PostConstructManager(BootupClasses bootupClasses) {
|
||||
this.list = bootupClasses.getBeanPostConstructoListeners();
|
||||
}
|
||||
|
||||
public int getRegisterCount() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register BeanPostLoad listeners for a given entity type.
|
||||
*/
|
||||
public void addPostConstructListeners(DeployBeanDescriptor<?> deployDesc) {
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
BeanPostConstructListener c = list.get(i);
|
||||
if (c.isRegisterFor(deployDesc.getBeanType())) {
|
||||
logger.debug("BeanPostLoad on[" + deployDesc.getFullName() + "] " + c.getClass().getName());
|
||||
deployDesc.addPostConstructListener(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import com.avaje.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
import com.avaje.ebean.event.BeanFindController;
|
||||
import com.avaje.ebean.event.BeanPersistController;
|
||||
import com.avaje.ebean.event.BeanPersistListener;
|
||||
import com.avaje.ebean.event.BeanPostConstructListener;
|
||||
import com.avaje.ebean.event.BeanPostLoad;
|
||||
import com.avaje.ebean.event.BeanQueryAdapter;
|
||||
import com.avaje.ebean.event.changelog.ChangeLogFilter;
|
||||
@@ -22,6 +23,7 @@ import com.avaje.ebeaninternal.server.deploy.BeanDescriptor.EntityType;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager;
|
||||
import com.avaje.ebeaninternal.server.deploy.ChainedBeanPersistController;
|
||||
import com.avaje.ebeaninternal.server.deploy.ChainedBeanPersistListener;
|
||||
import com.avaje.ebeaninternal.server.deploy.ChainedBeanPostConstructListener;
|
||||
import com.avaje.ebeaninternal.server.deploy.ChainedBeanPostLoad;
|
||||
import com.avaje.ebeaninternal.server.deploy.ChainedBeanQueryAdapter;
|
||||
import com.avaje.ebeaninternal.server.deploy.IndexDefinition;
|
||||
@@ -155,6 +157,7 @@ public class DeployBeanDescriptor<T> {
|
||||
private final List<BeanPersistListener> persistListeners = new ArrayList<BeanPersistListener>();
|
||||
private final List<BeanQueryAdapter> queryAdapters = new ArrayList<BeanQueryAdapter>();
|
||||
private final List<BeanPostLoad> postLoaders = new ArrayList<BeanPostLoad>();
|
||||
private final List<BeanPostConstructListener> postConstructListeners = new ArrayList<BeanPostConstructListener>();
|
||||
|
||||
private CacheOptions cacheOptions = CacheOptions.NO_CACHING;
|
||||
|
||||
@@ -175,8 +178,6 @@ public class DeployBeanDescriptor<T> {
|
||||
|
||||
private String name;
|
||||
|
||||
private boolean processedRawSqlExtend;
|
||||
|
||||
private ChangeLogFilter changeLogFilter;
|
||||
|
||||
private String dbComment;
|
||||
@@ -533,6 +534,19 @@ public class DeployBeanDescriptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BeanPostCreate(could be a chain of them, 1 or null).
|
||||
*/
|
||||
public BeanPostConstructListener getPostConstructListener() {
|
||||
if (postConstructListeners.isEmpty()) {
|
||||
return null;
|
||||
} else if (postConstructListeners.size() == 1) {
|
||||
return postConstructListeners.get(0);
|
||||
} else {
|
||||
return new ChainedBeanPostConstructListener(postConstructListeners);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPersistController(BeanPersistController controller) {
|
||||
persistControllers.add(controller);
|
||||
}
|
||||
@@ -549,6 +563,10 @@ public class DeployBeanDescriptor<T> {
|
||||
postLoaders.add(postLoad);
|
||||
}
|
||||
|
||||
public void addPostConstructListener(BeanPostConstructListener postConstructListener) {
|
||||
postConstructListeners.add(postConstructListener);
|
||||
}
|
||||
|
||||
public String getDraftTable() {
|
||||
return draftTable;
|
||||
}
|
||||
|
||||
@@ -688,22 +688,22 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
|
||||
customScalarTypes.add(longToTimestamp);
|
||||
|
||||
List<Class<?>> foundTypes = bootupClasses.getScalarTypes();
|
||||
List<Class<? extends ScalarType<?>>> foundTypes = bootupClasses.getScalarTypes();
|
||||
|
||||
for (int i = 0; i < foundTypes.size(); i++) {
|
||||
Class<?> cls = foundTypes.get(i);
|
||||
Class<? extends ScalarType<?>> cls = foundTypes.get(i);
|
||||
try {
|
||||
|
||||
ScalarType<?> scalarType;
|
||||
if (objectMapper == null) {
|
||||
scalarType = (ScalarType<?>) cls.newInstance();
|
||||
scalarType = cls.newInstance();
|
||||
} else {
|
||||
try {
|
||||
// first try objectMapper constructor
|
||||
Constructor<?> constructor = cls.getConstructor(ObjectMapper.class);
|
||||
scalarType = (ScalarType<?>) constructor.newInstance((ObjectMapper) objectMapper);
|
||||
Constructor<? extends ScalarType<?>> constructor = cls.getConstructor(ObjectMapper.class);
|
||||
scalarType = constructor.newInstance((ObjectMapper) objectMapper);
|
||||
} catch (NoSuchMethodException e) {
|
||||
scalarType = (ScalarType<?>) cls.newInstance();
|
||||
scalarType = cls.newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,7 +730,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected void initialiseScalarConverters(BootupClasses bootupClasses) {
|
||||
|
||||
List<Class<?>> foundTypes = bootupClasses.getScalarConverters();
|
||||
List<Class<? extends ScalarTypeConverter<?, ?>>> foundTypes = bootupClasses.getScalarConverters();
|
||||
|
||||
for (int i = 0; i < foundTypes.size(); i++) {
|
||||
Class<?> cls = foundTypes.get(i);
|
||||
@@ -766,7 +766,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
|
||||
protected void initialiseCompoundTypes(BootupClasses bootupClasses) {
|
||||
|
||||
List<Class<?>> compoundTypes = bootupClasses.getCompoundTypes();
|
||||
List<Class<? extends CompoundType<?>>> compoundTypes = bootupClasses.getCompoundTypes();
|
||||
for (int j = 0; j < compoundTypes.size(); j++) {
|
||||
|
||||
Class<?> type = compoundTypes.get(j);
|
||||
|
||||
Reference in New Issue
Block a user