Posted my current configuration
#Configuration
public class Config {
#Value("${spring.datasource.primary.jndi-name}")
private String primaryJndiName;
#Value("${spring.datasource.secondary.jndi-name}")
private String secondaryJndiName;
#Primary
#Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability
public DataSource primaryDs() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource(primaryJndiName);
}
#Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability
public DataSource secondaryDs() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource(secondaryJndiName);
}
}
I implemented this way and it is working
you can put your jndi values in one properties file and then load that property file in your bean defination.xml
jndi.properties
#JNDI property for job repository
job.repository.db.connection=jdbc/pgDB
#JNDI property for application
application.db.connection=jdbc/db2Conn
Bean-defination.xml
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:/properties/jndi.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
<bean id="jobRepoDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${job.repository.db.connection}" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${application.db.connection}" />
</bean>
I'm trying to inject a list of Class. I want a list of classes, not objects.
My class looks like this:
public class CodeServiceImpl{
private List<Class<?>> codeList;
// getter and setter
My spring configuration file (I'm not using annotations but xml) is
<bean id="myCodeServiceImpl" class = "net.croz.service.CodeServiceImpl">
<property name="codeList">
<list>
<ref bean="myAddress"/>
<ref bean="myCity"/>
<ref bean="myCountry"/>
</list>
</property>
</bean>
<bean id="myAddress" class="java.lang.Class" factory-method="forName">
<constructor-arg value="net.croz.model.Address"/>
</bean>
<bean id="myCity" class="java.lang.Class" factory-method="forName">
<constructor-arg value="net.croz.model.City"/>
</bean>
<bean id="myCountry" class="java.lang.Class" factory-method="forName">
<constructor-arg value="net.croz.model.Country"/>
</bean>
But the list codeList isn't being populated. It ends up being a null object. Thank you for your help.
Actually it works as is:
<bean class="com.my.proj.Foo">
<constructor-arg value="java.lang.String, org.springframework.util.StringUtils, byte[]"/>
</bean>
where Foo is:
public class Foo {
private final List<Class<?>> codeList;
public Foo(Class<?>... codeList) {
this.codeList = Arrays.asList(codeList);
}
}
The ConversionService does the stuff for converting comma-separated string to the Class<?>[] and tries to resolve each class on its own using BeanClassLoader
Take the following configuration:
<beans>
<bean name="myToyota" class="Car">
<property name="contents">
<list>
<bean class="Wheel">
<property name="designation"><value>front-left</value></property>
<property name="parent"><ref bean="myToyota"/></property>
</bean>
<bean class="Wheel">
<property name="designation"><value>front-right</value></property>
<property name="parent"><ref bean="myToyota"/></property>
</bean>
</list>
</property>
</bean>
</beans>
Is it possible to build this graph without directly referencing myToyota from the Wheel beans? (Maybe using SpEL).
My concern is that I can not copy-paste the description of the Wheels to an other Car bean without introducing the possibility of broken references (that's me forgetting to adjust the parent property by hand).
In other words: is there a way an inner bean can referece it's containing bean without knowing its name?
What if you do something like the following:
public class Car {
private List contents;
public List getContents() {
return contents;
}
public void setContents(List contents) {
this.contents = contents;
for (Iterator iterator = contents.iterator(); iterator.hasNext();) {
Wheel object = (Wheel) iterator.next();
object.setParent(this);
}
}
}
I am working in broadleaf which is based on spring-mvc.
there are 3-4 blCustomPersistenceHandlers bean definition in different xml file based on project module.
<bean id="blCustomPersistenceHandlers" class="org.springframework.beans.factory.config.ListFactoryBean" scope="prototype">
<property name="sourceList">
<list>
<bean class="org.broadleafcommerce.admin.server.service.handler.CategoryCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.admin.server.service.handler.CustomerPasswordCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.openadmin.server.security.handler.AdminUserCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.admin.server.service.handler.CustomerCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.admin.server.service.handler.ProductCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.admin.server.service.handler.ChildCategoriesCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.admin.server.service.handler.SkuCustomPersistenceHandler"/>
</list>
</property>
</bean>
below in different xml files
<bean id="blCustomPersistenceHandlers" class="org.springframework.beans.factory.config.ListFactoryBean" scope="prototype">
<property name="sourceList">
<list>
<bean class="org.broadleafcommerce.cms.admin.server.handler.PageTemplateCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.cms.admin.server.handler.StructuredContentTypeCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.cms.admin.server.handler.SandBoxItemCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.cms.admin.server.handler.PendingSandBoxItemCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.cms.admin.server.handler.TimeDTOCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.cms.admin.server.handler.RequestDTOCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.cms.admin.server.handler.StructuredContentItemCriteriaCustomPersistenceHandler"/>
<bean class="org.broadleafcommerce.cms.admin.server.handler.PageItemCriteriaCustomPersistenceHandler"/>
</list>
</property>
</bean>
Above definitions reside into jar files that we included.
Now i want to replace one of this handler , for example ProductCustomPersistenceHandler,
I need to change some functionality regarding that handler, so I changed that handler as below in my xml file.
<bean id="org.broadleafcommerce.admin.server.service.handler.ProductCustomPersistenceHandler"
class="com.mycompany.server.service.handler.HCProductCustomPersistenceHandler" />
and also put bean defination into xml files
<bean id="blCustomPersistenceHandlers" class="org.springframework.beans.factory.config.ListFactoryBean"> <!-- scope="prototype" -->
<property name="sourceList">
<list>
<bean class="com.mycompany.server.service.handler.HCProductCustomPersistenceHandler"/>
</list>
</property>
</bean>
ProductCustomPersistenceHandler class
public class ProductCustomPersistenceHandler extends CustomPersistenceHandlerAdapter {
#Resource(name = "blCatalogService")
protected CatalogService catalogService;
private static final Log LOG = LogFactory.getLog(ProductCustomPersistenceHandler.class);
#Override
public Boolean canHandleAdd(PersistencePackage persistencePackage) {
String ceilingEntityFullyQualifiedClassname = persistencePackage.getCeilingEntityFullyQualifiedClassname();
String[] customCriteria = persistencePackage.getCustomCriteria();
return !ArrayUtils.isEmpty(customCriteria) && "productDirectEdit".equals(customCriteria[0]) && Product.class.getName().equals(ceilingEntityFullyQualifiedClassname);
}
#Override
public Boolean canHandleUpdate(PersistencePackage persistencePackage) {
return canHandleAdd(persistencePackage);
}
#Override
public Entity add(PersistencePackage persistencePackage, DynamicEntityDao dynamicEntityDao, RecordHelper helper) throws ServiceException {
Entity entity = persistencePackage.getEntity();
try {
PersistencePerspective persistencePerspective = persistencePackage.getPersistencePerspective();
Product adminInstance = (Product) Class.forName(entity.getType()[0]).newInstance();
Map<String, FieldMetadata> adminProperties = helper.getSimpleMergedProperties(Product.class.getName(), persistencePerspective);
adminInstance = (Product) helper.createPopulatedInstance(adminInstance, entity, adminProperties, false);
adminInstance = (Product) dynamicEntityDao.merge(adminInstance);
CategoryProductXref categoryXref = new CategoryProductXrefImpl();
categoryXref.setCategory(adminInstance.getDefaultCategory());
categoryXref.setProduct(adminInstance);
if (adminInstance.getDefaultCategory() != null && !adminInstance.getAllParentCategoryXrefs().contains(categoryXref)) {
categoryXref = (CategoryProductXref) dynamicEntityDao.merge(categoryXref);
adminInstance.getAllParentCategoryXrefs().add(categoryXref);
}
//Since none of the Sku fields are required, it's possible that the user did not fill out
//any Sku fields, and thus a Sku would not be created. Product still needs a default Sku so instantiate one
if (adminInstance.getDefaultSku() == null) {
Sku newSku = catalogService.createSku();
adminInstance.setDefaultSku(newSku);
adminInstance = (Product) dynamicEntityDao.merge(adminInstance);
}
//also set the default product for the Sku
adminInstance.getDefaultSku().setDefaultProduct(adminInstance);
dynamicEntityDao.merge(adminInstance.getDefaultSku());
return helper.getRecord(adminProperties, adminInstance, null, null);
} catch (Exception e) {
LOG.error("Unable to add entity for " + entity.getType()[0], e);
throw new ServiceException("Unable to add entity for " + entity.getType()[0], e);
}
}
#Override
public Entity update(PersistencePackage persistencePackage, DynamicEntityDao dynamicEntityDao, RecordHelper helper) throws ServiceException {
Entity entity = persistencePackage.getEntity();
try {
PersistencePerspective persistencePerspective = persistencePackage.getPersistencePerspective();
Map<String, FieldMetadata> adminProperties = helper.getSimpleMergedProperties(Product.class.getName(), persistencePerspective);
Object primaryKey = helper.getPrimaryKey(entity, adminProperties);
Product adminInstance = (Product) dynamicEntityDao.retrieve(Class.forName(entity.getType()[0]), primaryKey);
adminInstance = (Product) helper.createPopulatedInstance(adminInstance, entity, adminProperties, false);
adminInstance = (Product) dynamicEntityDao.merge(adminInstance);
CategoryProductXref categoryXref = new CategoryProductXrefImpl();
categoryXref.setCategory(adminInstance.getDefaultCategory());
categoryXref.setProduct(adminInstance);
if (adminInstance.getDefaultCategory() != null && !adminInstance.getAllParentCategoryXrefs().contains(categoryXref)) {
adminInstance.getAllParentCategoryXrefs().add(categoryXref);
}
return helper.getRecord(adminProperties, adminInstance, null, null);
} catch (Exception e) {
LOG.error("Unable to update entity for " + entity.getType()[0], e);
throw new ServiceException("Unable to update entity for " + entity.getType()[0], e);
}
}
}
I just extend this handler and make my new handler , as it runs only core handler is executing, I want to execute my handler.
But this is not working.
I can't change into core part, so I just need to replace handler with my handler.
How can I do that?
Is that possible in spring?
For custom persistence handlers specifically, you can remove the core handlers by using the blCustomPersistenceHandlerFilters bean. So in your case you would define your beans like this:
<bean id="blCustomPersistenceHandlerFilters" class="org.springframework.beans.factory.config.ListFactoryBean" scope="prototype">
<property name="sourceList">
<list>
<bean class="org.broadleafcommerce.openadmin.server.service.handler.DefaultCustomPersistenceHandlerFilter">
<property name="filterCustomPersistenceHandlerClassnames">
<list>
<value>org.broadleafcommerce.admin.server.service.handler.ProductCustomPersistenceHandler</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
Then you can add your own CPH to the list like you were doing before:
<bean id="blCustomPersistenceHandlers" class="org.springframework.beans.factory.config.ListFactoryBean"> <!-- scope="prototype" -->
<property name="sourceList">
<list>
<bean class="com.mycompany.server.service.handler.HCProductCustomPersistenceHandler"/>
</list>
</property>
</bean>
And now the BLC Product custom persistence handler will not run but yours will.
This is probably a little too complex for your simple purposes of wanting to replace the out-of-the-box one with your custom one. It's possible that there is a good reason why we did it like this, but I added a GitHub Issue for it to investigate further.
I have an enum ContentType and it has a method like ContentType.getName() which can evaluate to regText OR session. So, how do I do the below where I can instantiate the bean based on the return value of this method. Also, I only want to do this in XML config and not annotations.
<property name="contentCaptureRegEx" ref="${ContentType.getName()}">
</property>
<bean id="regText" class="java.util.regex.Pattern" factory-method="compile" lazy-init="true">
<constructor-arg value="xyz" /></bean>
<bean id="session" class="java.util.regex.Pattern" factory-method="compile" lazy-init="true">
<constructor-arg value="abc" /></bean>
I would suggest a static factory method since the pattern regexes are already using that pattern. Just eliminate them and add:
package com.mine;
public class MyFactory {
public static Pattern newContentCaptureRegEx() {
String patternString;
if ("regText".equals(ContentType.getName())) {
patternString = "xyz";
} else if ("session".equals(ContentType.getName())) {
patternString = "abc";
} else {
throw new IllegalStateException("ContentType must be regText or session");
}
Pattern.compile(patternString);
}
}
which you can wire as:
<bean id="ContentCaptureRegEx" class="com.mine.MyFactory"
factory-method="newContentCaptureRegEx" />
And then you can ref that bean anywhere as:
<property name="contentCaptureRegEx" ref="ContentCaptureRegEx" />