I have an AOP proxy bean defined as follows:
<bean id="someService" class="..FactoryBean">
..
<property name="target">
<ref local="target" />
</property>
<property name="preInterceptors"><ref local="serviceInterceptors"/></property>
..
</bean>
a target bean:
<bean id="target" class=".." />
and a child to the target bean:
<bean parent="target">
<!-- set some properties -->
</bean>
I'd like to change the target bean to an anonymous bean, but maintain the child bean. The only problem is setting parent attribute of child bean to AOP proxy bean inherits from the factory bean and not the target bean. Is there a work around for this?
Not pretty, but it should work:
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="com.foo.bar.ExampleService" />
</property>
</bean>
<bean id="targetSource" factory-bean="proxy" factory-method="getTargetSource" />
<bean id="parent" factory-bean="targetSource" factory-method="getTarget" />
<bean parent="parent" />
Related
I have the requirement to remove all passwords and encryption keys from the source code of my project. I'm struggling to get this to work in my spring-servlet.xml file.
This worked before I tried making the change:
the database username, encrypted password, URL and driver were defined in a file jdbc_server.properties as a classpath resource.
the encryption/decryption key was passed on start-up as -DENCRYPTION_PASSWORD=
I want to move the jdbc_server_properties file to the filesystem and include the key in the file.
This is my last (of at least 25) attempt at getting this to work.
<bean id="propertyConfigurer" class="org.jasypt.spring4.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="standardEncryptor" />
<property name="jdbcUsername" value="JDBC_USERNAME" />
<property name="jdbcPassword" value="JDBC_PASSWORD" />
<property name="jdbcUrl" value="JDBC_URL" />
<property name="jdbcDriver" value="JDBC_DRIVER" />
<property name="locations">
<list>
<value>file:///${USERPROFILE}/credentials/jdbc_server.properties</value>
</list>
</property>
</bean>
<bean id="standardEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config" ref="environmentVariablesConfiguration" />
</bean>
<bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="passwordSysPropertyName" value="ENCRYPTION_PASSWORD" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbcDriver}" p:url="${jdbcUrl}"
p:username="${jdbcUsername}" p:password="${jdbcPassword}">
</bean>
Using the above configuration, I get a NotWritablePropertyException exception. I've seen tons of posts on this issue but not where both the properties and encryption key are in a file on the filesystem.
When this was working and the properties were read from a file in the classpath, there were no getters/setters for jdbcUsername (or the other properties) so I don't know why it's failing in this way now.
I tried adding the getters and setters (as String) to my BaseDaoImpl class but I still get the same error so if I'm supposed to add them, I'm not sure where they go.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'propertyConfigurer' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'jdbcUsername' of bean class [org.jasypt.spring4.properties.EncryptablePropertyPlaceholderConfigurer]: Bean property 'jdbcUsername' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1568)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1276)
at ...
That is probably because jdbcUsername is not a property of EncryptablePropertyPlaceholderConfigurer.
Please, try something like this (just remove the jdbc* properties from the EncryptablePropertyPlaceholderConfigurer configuration, and use it directly in your dataSource bean):
<bean id="propertyConfigurer" class="org.jasypt.spring4.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="standardEncryptor" />
<property name="locations">
<list>
<value>file:///${USERPROFILE}/credentials/jdbc_server.properties</value>
</list>
</property>
</bean>
<bean id="standardEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config" ref="environmentVariablesConfiguration" />
</bean>
<bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="passwordSysPropertyName" value="ENCRYPTION_PASSWORD" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${JDBC_DRIVER}" p:url="${JDBC_URL}"
p:username="${JDBC_USERNAME}" p:password="${JDBC_PASSWORD}">
</bean>
Assuming your jdbc_server.properties file contains the required information:
JDBC_USERNAME=ENC(...)
JDBC_PASSWORD=ENC(...)
JDBC_URL=ENC(...)
JDBC_DRIVER=your.jdbc.driver
I'm extending a complete product called Hippo CMS with my own REST interface. Hippo CMS is using Apache CXF for rest and acquires resources definitions from a spring bean defined somewhere in Hippo CMS sources. This definition look like this:
<bean id="jaxrsRestPlainResourceProviders" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.apache.commons.collections.ListUtils" />
<property name="targetMethod" value="union" />
<property name="arguments">
<list>
<ref bean="customRestPlainResourceProviders" />
<ref bean="defaultRestPlainResourceProviders" />
</list>
</property>
</bean>
<bean id="defaultRestPlainResourceProviders" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
</list>
</property>
</bean>
<!-- Default empty list of custom plain resource providers to be overriden. -->
<bean id="customRestPlainResourceProviders" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
</list>
</property>
</bean>
I need to override customRestPlainResourceProviders bean with my own bean. It works fine from XML configuration looking like this:
<bean id="customRestPlainResourceProviders" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<bean class="org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider">
<constructor-arg>
<bean class="com.xxx.rest.FolderStructureResource"/>
</constructor-arg>
</bean>
</list>
</property>
</bean>
But it doesn't work if I define a bean in Java configuration class (which in the case of other beans works completely fine):
#Bean(name = "customRestPlainResourceProviders")
public ListFactoryBean customRestPlainResourceProviders() {
ListFactoryBean listFactoryBean = new ListFactoryBean();
listFactoryBean.setSourceList(
Lists.newArrayList(
new SingletonResourceProvider(
new FolderStructureResource(repository())
)
)
);
return listFactoryBean;
}
Is there a way to override a bean defined in XML configuration with a bean created in Java configuration class?
What version of spring are you using? I believe this issues is addressed in 4.2.
I have a PropertyPlaceholderConfigurer that loads multiple properties files. I want to inject the merged properties map into a Spring Bean via config XML.
Can I do that and how?
You could just create a properties bean and use that for your PropertyPlaceholderConfigurer and your Config bean:
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:default.properties</value>
<value>classpath:someother.properties</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="myProperties" />
</bean>
<bean id="myConfigBean" class="my.pkg.Config">
<constructor-arg ref="myProperties" />
</bean>
I want to be able to pass a bean ID into another bean by reference. So if I have this:
<bean id="specialName" class="my.SpecialBean"/>
<bean id="referenceBean" class="my.ReferenceBean">
<property name="refId" value="<specialName.name>"/>
</bean>
public class ReferenceBean {
// The spring injected value of this should be 'specialName'
public String refId;
// getter & setter for refId
}
The reason I need this, it that ReferenceBean is actually a route builder in Camel and it directs messages to SpecialBean through the Spring Registry. I'm new to Spring and Camel, so if this is an ill conceived questions, my apologies.
You can use Spring-EL -
<bean id="specialName" class="my.SpecialBean"/>
<bean id="referenceBean" class="my.ReferenceBean">
<property name="refId" value="#{specialName.name}"/>
</bean>
Why not just put the id statically into refId there? It will not change later so why should you do something complicated here?
<bean id="specialName" class="my.SpecialBean"/>
<bean id="referenceBean" class="my.ReferenceBean">
<property name="refId" value="specialName"/>
</bean>
What about:
<bean id="specialName" class="my.SpecialBean" />
<bean id="referenceBean" class="my.ReferenceBean">
<property name="refId" ref="specialName" />
</bean>
This way your bean should be injected (provided you change the String attribute in my.SpecialBean.
Then you can get any attribute you want.
You could use the idref element (see Spring XML Beans Schema):
<bean id="specialName" class="my.SpecialBean"/>
<bean id="referenceBean" class="my.ReferenceBean">
<property name="refId">
<idref bean="specialName"/>
</property>
</bean>
I have the hibernate-context
<context:property-placeholder location="/WEB-INF/spring.properties" />
<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Declare the Hibernate SessionFactory for retrieving Hibernate sessions -->
<!-- See http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.html -->
<!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/SessionFactory.html -->
<!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource"
p:configLocation="${hibernate.config}"
p:packagesToScan="com.vaannila"/>
<!-- Declare a datasource that has pooling capabilities-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}"
p:user="${app.jdbc.username}"
p:password="${app.jdbc.password}"
p:acquireIncrement="5"
p:idleConnectionTestPeriod="60"
p:maxPoolSize="100"
p:maxStatements="50"
p:minPoolSize="10" />
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
</beans>
now i want to pass sessionFactory in my constructor of DAO like below
<bean id="registrationDAO" class="com.vaannila.dao.RegistrationDAOimpl" >
<constructor-arg ref="sessionFactory"/>
</bean>
but error says that bean sessionfactory not found
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'registrationDAO' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sessionFactory' is defined
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
This work for me
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:/hibernate.cfg.xml</value>
</property>
<property name="dataSource" ref="dataSource">
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory" />
</bean>
<bean class="com.vaannila.dao.RegistrationDAOimpl"
id="registrationDAO">
<property name="sessionFactory">
<ref bean="hibernateSessionFactory" />
</property>
</bean>