I have a profiles.xml:
<?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:util="http://www.springframework.org/schema/util"
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/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Local -->
<beans profile="local">
<util:properties id="localProperties">
<prop key="property">localProperty</prop>
</util:properties>
<context:property-placeholder properties-ref="localProperties" ignore-unresolvable="true" />
</beans>
<!-- Dev -->
<beans profile="dev">
<util:properties id="devProperties">
<prop key="property">devProperty</prop>
</util:properties>
<context:property-placeholder properties-ref="devProperties" ignore-unresolvable="true" />
</beans>
</beans>
and I have a org.springframework.ws.client.support.interceptor.ClientInterceptor that I want to use values from profiles.xml:
#Component
public class HeaderInjector implements ClientInterceptor {
#Value("${property}")
private static String someProperty;
#Override
public boolean handleRequest(MessageContext messageContext)
throws WebServiceClientException {
//want to use someProperty here based on value from profiles.xml
}
}
How can I do this? I tried adding #ImportResource("profiles.xml") at the top of the class like
#Component
#ImportResource("profiles.xml")
public class SoapLeadPipeHeaderInjector implements ClientInterceptor {
but someProperty never gets set.
First of all there is nothing about Spring Integration in your question, so be careful with choosing tags for questions.
#ImportResource("profiles.xml") can be applied on the #Configuration class if you start application context from annotations.
If your main entry point is XML configuration, your #Component must be scanned via <context:component-scan base-package="..."/> then.
See more info in the Spring Framework Reference Manual.
Related
I am facing an issue while calling the service first time it's thrown error org.springframework.dao.TransientDataAccessResourceException: SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronizationsecond time the data retrieve successfully.
UserServiceEJB.java
#Stateless(name = "UserService")
#Interceptors
#Transactional
#TransactionAttribute(TransactionAttributeType.REQUIRED)
#Local(UserService.class)
public class UserServiceEJB implements UserService {
public UsersDetailsPojo[] getUsersList(UserRequest userRequest) {
return getUsers(userRequest);
}
}
config.xml
<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:jee="http://www.springframework.org/schema/jee"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
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">
<!-- MyBatis SqlSessionFactory -->
<bean id="mybatisTransactionManager" class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" c:_0-ref="sqlSessionFactory" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml"
p:transactionFactory-ref="mybatisTransactionManager" />
Getting below error
org.springframework.dao.TransientDataAccessResourceException: SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization
at org.mybatis.spring.SqlSessionUtils.registerSessionHolder(SqlSessionUtils.java:142)
at org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:102)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:428)
at com.sun.proxy.$Proxy123.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:230)
Is there any suggestions? Please help.
I can define an externalized configuration with this.
#Configuration
public class PropertiesConfig {
#Configuration
#PropertySource("classpath:test.properties")
#Profile("test")
static class DefaultConfig {
}
Also I can import a xml configuration using #ImportResource
In xml I also define an externalized configuration with 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: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.xsd">
<bean id="testProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:staging.properties"/>
</bean>
<context:property-placeholder order="1" properties-ref="testProperties"/>
</beans>
test.properties have url=www.facebook.com
staging.properties have url=www.google.com
It seems using ${url} always got url of test.properties.
How using xml configuration to cover the #PropertySource?
I have a properties file in src/main/resources.
Spring 4.0 and Java 1.8 project.
mock.properties
key=test
WEB-INF/web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
WEB-INF/mvc-dispatcher-servlet.xml
<context:component-scan base-package="com.x.y.z.*">
</context:component-scan>
<context:annotation-config />
<context:spring-configured />
<context:property-placeholder location="classpath:mock.properties"
order="-1" ignore-resource-not-found="true" ignore-unresolvable="true" />
<mvc:annotation-driven />
Controller.java ... I can access the value of property key in controller.
#Controller
#RequestMapping("/xyz")
public class EC2Controller {
#Value("${key}")
String v;
}
Helper.java ... Can't access any property.Always gets "null"
#Component
public class Helper {
#Value("${key}")
String v;
}
I also tried various options suggested on forums and spring docs but helper is just not able to read the prop.I tried following as well
#Configuration
#PropertySource("classpath:mock.properties")
public class Helper {
#Value("${key}")
String v;
#Bean
public static PropertySourcesPlaceholderConfigurer
propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
and
#Configuration
#PropertySource("classpath:mock.properties")
public class Helper {
#Autowired
Environment env;
String v = env.getProperty("key");
}
nothing works.
The answer depends on whether you are using the springonfig.xml mvc-dispatcher-servlet.xml that you show above. Based on your code samples, it looks like you are not (unless there is something missing).
Your mvc-dispatcher-servlet.xml includes context:property-placeholder, so it should be sufficient. But if you are not using it, or want to use an #Configuration (Java config) class instead (you can mix xml and Java config in the same app) then you need a PropertySourcesPlaceHolderConfigurer to resolve ${} in #Value, such as:
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
See documentation at https://docs.spring.io/spring/docs/4.2.4.RELEASE/javadoc-api/org/springframework/context/annotation/PropertySource.html, which states:
In order to resolve ${...} placeholders in definitions or #Value annotations using properties from a PropertySource, one must register a PropertySourcesPlaceholderConfigurer...
Note that the documentation states this happens automatically when using context:property-placeholder in XML - but as noted it's not clear from your code samples whether you are using that.
You could try this code snippet, and use ${key} to inject value:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/demo.properties</value>
</list>
</property>
</bean>
or this, and use #{app.key} to inject value:
<?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:util="http://www.springframework.org/schema/util"
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
http://www.springframework.org/schema/util
http://www.springframework.org/schema/context/spring-util-3.2.xsd" profile="dev">
...
<util:properties id="app" location="app.properties" />
...
</beans>
Hope to help you.
Is there anyway to get beans loaded via <context:component-scan/> in a xml file to be proxy'ed by an #Coniguration annotated class which has #EnableCaching and declares the SimpleCacheManager? This would be the easiest route for the large applicaiton I'm working with, my ultimate preference would be to convert it all over to a Configuration class, but that is a lot more work and there are next to no unit tests for this application -.- , something would totally break. The other option is to declare the Cache's in the xml which works fine but I feel like is a step backwards.
NOTE: The <context:annotation-config/> is declared in a separate xml file 'integration.xml' I put it back in the applicationContext.xml but it didn't affect anything.
The declaration of the caches and the enabling of the caching via #EnableCaching was moved to the below java class some time ago and I don't think anyone noticed that it stopped working. So I would like to get it working again in the best way.
Application Context (edited for brevity)
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
"
>
<util:properties id="properties" location="classpath:config.properties"/>
<context:property-placeholder properties-ref="properties"/>
<!-- TODO: Replace this with MethodInvokingBean - we don't actually *want* a ConfigFactory instance -->
<bean id="configFactory" class="net.adl.service.ConfigFactory">
<property name="properties" ref="properties" />
</bean>
<!-- Enable Caching -->
<cache:annotation-driven proxy-target-class="true"/>
<!-- Declaring the cache manager and caches here works, but I feel is a step backwards to put them back in the XML config -->
<context:component-scan base-package="
net.adl.quartz,
net.adl.config,
net.adl.dao,
net.adl.service,
net.adl.audit,
net.adl.diagnostic,
net.adl.loader,
net.adl.loader"/>
<!-- add support for #Scheduled -->
<task:scheduler id="taskScheduler" pool-size="10"/>
<task:executor id="taskExecutor" pool-size="10"/>
<!-- Used for real time monitoring of folders for data loads -->
<task:executor id="realTimeAutoLoaderExecutor" pool-size="1"/>
<task:annotation-driven scheduler="taskScheduler" executor="taskExecutor"/>
<!-- enable #Transactional annotations -->
<bean id="transactionAdvice" class="net.adl.aop.TransactionAdvice"/>
<!--<bean id="profiler" class="net.adl.util.Profiler"/>-->
<aop:aspectj-autoproxy proxy-target-class="true">
<aop:include name="transactionAdvice"/>
<!--<aop:include name="profiler"/>-->
</aop:aspectj-autoproxy>
<!-- set system properties -->
<bean id="systemPrereqs" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<!--
"systemProperties" is predefined; see:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html#expressions-beandef-xml-based
-->
<property name="targetObject" value="#{#systemProperties}"/>
<property name="targetMethod" value="putAll"/>
<property name="arguments">
<util:properties>
<prop key="net.sf.ehcache.skipUpdateCheck">true</prop>
<prop key="org.terracotta.quartz.skipUpdateCheck">true</prop>
</util:properties>
</property>
</bean>
<!-- Exception translation bean post processor -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>
<bean id="versionInfo" class="net.adl.util.VersionInfo">
<property name="versionFilePath" value="${labmatrix.home}/version-info.txt"/>
</bean>
<!-- Here is where we call in the <context:annotation-config/>, not sure why its done in a separate file -->
<import resource="resources/spring/integration.xml"/>
</beans>
Integration.xml -- I think the idea is more deployment specific config options can go in this one
<?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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
"
>
<context:annotation-config/>
</beans>
MethodCachingConfiguration Class
package net.adl.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
#Configuration
#EnableCaching
public class MethodCacheConfiguration {
public static final String STUDY_CONFIG = "config.studies";
public static final String ACCESS_CONFIG = "config.access";
public static final String WORKFLOW_CONFIG = "config.workflows";
public static final String PROCESS_CONFIG = "config.processes";
public static final String QUERY_CONFIG = "config.queries";
public static final String AUTOLOADER_CONFIG = "config.autoloader";
public static final String LOCALIZATION = "localization";
public static final String FACTORY_CONFIG = "config.factories";
/**
* Configures the cacheManager bean for #Cacheable annotation support
*/
#Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(
new ConcurrentMapCache(STUDY_CONFIG),
new ConcurrentMapCache(ACCESS_CONFIG),
new ConcurrentMapCache(WORKFLOW_CONFIG),
new ConcurrentMapCache(PROCESS_CONFIG),
new ConcurrentMapCache(QUERY_CONFIG),
new ConcurrentMapCache(AUTOLOADER_CONFIG),
new ConcurrentMapCache(LOCALIZATION),
new ConcurrentMapCache(FACTORY_CONFIG)
));
return cacheManager;
}
}
EDIT: Fixed copy paste reformat typos
<cache:annotation-driven /> and #EnableCaching are equal you can have only one (maybe it can be source of your trouble) Can you provide example of code where you are actually using caching? Which bean should use cache feature.
Answer provided by chalimartines
i want to define an #Around aspect for a method of my #Entity
All my entities are in package data.entity
A define an aspect like this:
#Aspect
public class TestAspect {
#Around("execution(* data.entity..*(..))")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("INTERCEPT: "+pjp.toLongString());
return pjp.proceed();
}
}
But never is intercepted... where is my error?
In spring xml i have 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:tx="http://www.springframework.org/schema/tx"
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-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="data.dao, data.service" />
<tx:annotation-driven proxy-target-class="true"/>
<aop:aspectj-autoproxy/>
<bean id="testAspect" class="spring.TestAspect" />
... datasource and other ...
</beans>
I try also
#Around("target(data.entity.MyEntity)")
and
#Around("target(data.entity..)")
but still not work.
Thanks.
It looks like you use spring-proxy-aop. This works only if the class is a spring manged bean, and the adviced method must be invoked from an other object.
Try to use real aspectJ instead of spring-proxy-aop.
I have just started using AOP and below are the findings at my level
i am assuming you have necessary jar files, aspectjweaver-1.6.10.jar and org.springframework.aop-3.0.5.RELEASE.jar present in your apps classpath.
The method aroundAdvice, as you have defined currently is perfect.
Could you remove the below line and try.
<context:component-scan base-package="data.dao, data.service" />