Is there any way to resolve placeholder in beanName? - java

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.wqh">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:custom.properties</value>
</list>
</property>
</bean>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean class="com.wqh.demo.TestBean" name="${custom.beanName}" />
</beans>
When I use configuration like this, Spring will create BeanDefinition with beanName ${custom.beanName}, and will not resolve the placeholder inside it.
But I want to use the beanName which declared in custom.properties file, is there any way to achieve this requirement?

The following configuration would result in NoSuchBeanDefinitionException when attempting to get the bean from context.
<bean class="com.wqh.demo.TestBean" name="${custom.beanName}" />
However , the XML Template Proposals for attribute name shows the following
Attribute : name Can be used to create one or more aliases illegal in
an (XML) id. Multiple aliases can be separated by any number of
spaces, commas, or semi-colons (or indeed any mixture of the three).
Data Type : string
Based on this , the following work around is possible
Considering the properties file entry is :
custom.beanName=propBeanName
Provide the bean configuration with multiple alias names as follows
<bean class="com.wqh.demo.TestBean" name="testBeanName ${custom.beanName}" />
Now when you getBean() based on the name from the application context , it would retrieve the bean successfully
Sample code
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("app-context.xml");
System.out.println(Arrays.asList(ctx.getAliases("testBeanName")));
TestBean bean = (TestBean)ctx.getBean("propBeanName");
System.out.println(bean);
}
would display the following in the console
[propBeanName]
com.wqh.demo.TestBean#4c60d6e9

Related

primary attribute not allowed inside bean tag

I have tried to set the default validation message file to messages.properties file. It worked. However, for some reason the primary attribute inside validator bean is marked red in the applicationContext.xml file.
The error message, "Attribute primary is not allowed here".
I have tried to find the reason of this in many resources and cross-checked many possibilities, but everything seems fine with my configuration.
I use Intellij Idea, Spring version - 3.2.17 RELEASE, Hibernate version - 3.6.10.Final.
Can anyone explain the reason ?
applicationContext.xml -
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"
default-autowire="byName">
<context:component-scan base-package="com.test.leavemanagement"/>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"/>
</bean>
<mvc:annotation-driven validator="validator"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" primary="true">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
</beans>

MessageSource getMessage method not working in Spring mvc

I have developed a Spring mvc application where I want to read some property value
from properties file located inside of weblogic server.
Have performed following steps:
Created a project specific folder appConfig in following path: Oracle/Middleware/ORACLE_HOME/user_projects/domains/wl_server/config/rmsConfig
Placed the properties file named commonConfig.properties inside of it.
Have also edited setDomainEnv.cmd with following entry,
if NOT "%EXT_POST_CLASSPATH%"=="" (
set EXT_POST_CLASSPATH=%EXT_POST_CLASSPATH%;%DOMAIN_HOME%\config\appConfig
if NOT "%POST_CLASSPATH%"=="" (
set POST_CLASSPATH=%POST_CLASSPATH%;%EXT_POST_CLASSPATH%
) else (
set POST_CLASSPATH=%EXT_POST_CLASSPATH%
)
)
Please find below my Spring bean configuration file for this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="commonProps" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="commonConfig" />
<property name="cacheSeconds" value="120" />
</bean>
</beans>
In my Java Spring bean class I am refering to this as follows:
#Component
public class LocationClient{
#Autowired
private MessageSource commonProps;
public void showMessage(){
System.out.println(commonProps.getMessage("common.line", null, null, null));
}
}
Now commonProps is not null but "common.line" printing null in console.
Please find below property file entry:
common.line=382
Anyone has any suitable solution to this???
I think you have to add your property file in classpath or in WEB-INF folder.
This is the note from the Java Spring docs.
For a typical web application, message files could be placed in
WEB-INF: e.g. a "WEB-INF/messages" basename would find a
"WEB-INF/messages.properties", "WEB-INF/messages_en.properties" etc
arrangement as well as "WEB-INF/messages.xml",
"WEB-INF/messages_en.xml" etc. Note that message definitions in a
previous resource bundle will override ones in a later bundle, due to
sequential lookup.
Refer the link for more information: ReloadableResourceBundleMessageSource
One possible solution is to use ResourceBundleMessageSource instead of ReloadableResourceBundleMessageSource in order to define your properties like this:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="commonConfig" />
</bean>
Also make sure that commonConfig.properties is inside of your WEB-INF folder, for example if your application is appConfig then it should be on the root of your classpath: appConfig/WEB-INF/classes/commonConfig.properties
Second alternative if you need commonConfig.properties outside classpath, using your first approach (make sure that the bean id is messageSource)
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="file:/your/absoulute/path/commonConfig" />
<property name="cacheSeconds" value="120" />
</bean>

Spring ClassPathXmlApplicationContext creating an empty instance of all beans in spring conf file?

I m playing with Spring.
I created a Spring beans file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="hibernate.entities" />
<bean id="sicknessLeprosa" class="hibernate.entities.Sickness" init-method="print" scope="prototype">
<property name="nom" value="Leprosa" />
</bean>
<bean id="sicknessSclerosa" class="hibernate.entities.Sickness" init-method="print" scope="prototype">
<property name="nom" value="Sclerosa" />
</bean>
</beans>
When I call:
ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Module-Annotations.xml");
Map<String, Sickness> SicknessList = context.getBeansOfType(Sickness.class);
System.out.println("Number of ISickness beans: " + SicknessList.size() );
for(Entry<String, Sickness> entry : SicknessList.entrySet() ){
System.out.print(entry.getKey() + ": ");
entry.getValue().print();
}
I get this output:
Number of ISickness beans: 3
sickness: undefined sickness
sicknessLeprosa: Leprosa
sicknessSclerosa: Sclerosa
Where does the first occurence come from?????????????
It looks it comes from :
new ClassPathXmlApplicationContext("Spring-Module-Annotations.xml");
which seems to create an instance of Sickness when invoked.
Thx in advance
As you are using component scanning this will scan your base package recursively and try to find classes annotated with stereotype annotations (such as #Component, #Service, #Repository...). I guess your Sickness class is annotated with one of these. In that case the container will initialize it and that's why you get the first bean. The other two beans are explicitly defined in the configuration class.
BTW, you don't need <context:annotation-driven/> if you are using <context:component-scan />

Spring Conditional Bean creation based on another bean

I'm trying to find a way to only create a bean if the value of another bean/property is true, using Spring 3.2 and XML configurations.
<bean id="isEnabled" class="java.lang.Boolean">
<bean factory-bean="configurationService" factory-method="getBooleanValue">
<constructor-arg index="0">
<util:constant static-field="org.code.ConfigurationKeys.ENABLED"/>
</constructor-arg>
</bean>
</bean>
<if isEnabled=true>
..... create some beans
</if>
I've seen some slightly similar examples using Spring EL but nothing that does this exactly...
You can use profiles.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd" >
<!-- here goes common beans -->
<beans profile="Prof_1">
<import resource="./first-config.xml" />
</beans>
<beans profile="Prof_2">
<import resource="./second-config.xml" />
</beans>
</beans>
One can activate multiple profile at same time or choose not to activate any. To activate there are multiple ways but to programtaically do this we need to add a initializer in web.xml
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.test.MyCustomInitializer</param-value>
</context-param>
MyCustomInitializer looks like following
public class MyCustomInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
try {
String activeProf;
// some logic to either read file/env variable/setting to determine which profile to activate
applicationContext.getEnvironment().setActiveProfiles( activeProf );
} catch (IOException e) {
e.printStackTrace();
}
}
}
Why you don't use the factory to create the objects when are required and make them lazy.
<bean id="second "class="xxx.xxx.Class" lazy-init="true" scope="prototype"/>
There is no way to introduce if statement within the spring configuration, profiles could work but at more related to environment not a programmatic configuration.

spring-Unnamed bean definition specifies neither 'class' nor 'parent' nor 'factory-bean' - can't generate bean name

I met a problem below
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unnamed bean definition specifies neither 'class' nor 'parent' nor 'factory-bean' - can't generate bean name
Offending resource: ServletContext resource [/WEB-INF/sample-servlet.xml]
sample-servlet.xml code
,i don't know how to fix it
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.spring.controller"/>
<bean p:viewClass="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/pages/"
p:suffix=".jsp"/>
</beans>
is there someone who can help me? Thanks a lot!
Your bean definition
<bean p:viewClass="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/pages/"
p:suffix=".jsp"/>
doesn't declare a class attribute which is mandatory in this case. It should be
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="some view class"
p:prefix="/WEB-INF/pages/"
p:suffix=".jsp"/>
The p:viewClass attribute is referring to the property named viewClass in the InternalResourceViewResolver class. Obviously, set an appropriate value, maybe org.springframework.web.servlet.view.JstlView or org.springframework.web.servlet.view.InternalResourceView.
This and more are explained in the official documentation.

Categories