PropertyPlaceholderConfigurer: Use external properties file - spring

How to configure PropertyPlaceholderConfigurer to use properties files relative (some directories up) to the war?
We have running a war multiple times and each war should read its configuration for example from ../../etc/db.properties.
Update:
Yes, the properties files are outside the war. The directory structure is:
/htdocs/shop/live/apache-tomat/webapps/shop.war
should read
/htdocs/shop/live/etc/db.properties
and
/htdocs/shop/test/apache-tomat/webapps/shop.war
should read
/htdocs/shop/test/etc/db.properties

Finally, we have introduced a new resource type "relative:":
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:db.properties</value>
<value>relative:../../../etc/db.properties</value>
</list>
</property>
</bean>
We have extended XmlWebApplicationContext to inject custom resource handling:
public class Context extends XmlWebApplicationContext {
#Override
public Resource getResource(String location) {
if (location.startsWith(RelativeResource.RELATIVE_URL_PREFIX)) {
String relativePath = location.substring(RelativeResource.RELATIVE_URL_PREFIX.length());
return new RelativeResource(getServletContext(), relativePath);
}
return super.getResource(location);
}
}
Here is the relative resource class:
public class RelativeResource extends AbstractResource {
public static final String RELATIVE_URL_PREFIX = "relative:";
private final ServletContext servletContext;
private final String relativePath;
public RelativeResource(ServletContext servletContext, String relativePath) {
this.servletContext = servletContext;
this.relativePath = relativePath;
}
#Override
public String getDescription() {
return "RelativeResource [" + relativePath + "]";
}
#Override
public boolean isReadable() {
return true;
}
#Override
public boolean isOpen() {
return true;
}
#Override
public InputStream getInputStream() throws IOException {
String rootPath = WebUtils.getRealPath(servletContext, "/");
if (!rootPath.endsWith(File.separator)) rootPath += File.separator;
String path = rootPath + relativePath;
return new FileInputStream(path);
}
}

My code, based on mazatwork solution:
public class RelativeResource extends AbstractResource {
private final String relativePath;
public RelativeResource(String relativePath) {
this.relativePath = relativePath;
}
#Override
public String getDescription() {
return "RelativeResource [" + relativePath + "]";
}
#Override
public boolean isReadable() {
File resourceFile = new File(getAbsoluteFileLocation());
return resourceFile.exists();
}
#Override
public boolean isOpen() {
return true;
}
#Override
public InputStream getInputStream() throws IOException {
return new FileInputStream(getAbsoluteFileLocation());
}
private String getAbsoluteFileLocation() {
return Paths.get("").toAbsolutePath().resolve(relativePath).toString();
}
}
After that we can write in xml for example:
<bean id="configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value type="com.blabla.RelativeResource">overrideProperties.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>
Pros of this method - you don't hack Spring Context and don't stick to this hacked context implementation, you can use any (for example, not XmlWebApplicationContext, but ClassPathXmlApplicationContext) from Spring distribution.

In your configuration you can specify the properties from the classpath instead of relative to the configuration file.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:com/foo/jdbc.properties"/>
</bean>
For this to work you must make sure that the properties file makes it to the classpath.

Somehow I wasn't able to get the desired path following others' methods, so here is my working version, based primarily on Dmitry's answer (usage in xml is identical), while isReadable() and getInputStream() looks more like mazatwork's version:
public class RelativeResource extends AbstractResource {
private final String relativePath;
public RelativeResource(String relativePath) {
this.relativePath = relativePath;
}
#Override
public String getDescription() {
return "RelativeResource [" + relativePath + "]";
}
#Override
public boolean isReadable() {
return true;
}
#Override
public boolean isOpen() {
return true;
}
#Override
public InputStream getInputStream() throws IOException {
String rootPath = this.getClass().getResource("/").getPath();
rootPath = URLDecoder.decode(rootPath, "UTF-8");
if (!rootPath.endsWith(File.separator)) rootPath += File.separator;
String path = rootPath + relativePath;
return new FileInputStream(path);
}
}

Related

Spring Aop ProxyFactoryBean and ProxyFactory and ClassCastException

When i use ProxyFactoryBean to get proxy object, I get a ClassCastException,but when i use ProxyFactory's getProxy() to get a proxy object, it works properly. I use Spring 4.x.
Definition of Two Beans,WaiterTest and Seller:
public class WaiterTest {
public void greetTo(String name){
System.out.println("waiter greet to " + name +"...");
}
public void serveTo(String name){
System.out.println("waiter serving " + name + "...");
}
}
public class Seller {
public void greetTo(String name){
System.out.println("seller greet to " +name + "...");
}
}
Definition of Advice:
public class GreetingBeforeAdvice implements MethodBeforeAdvice{
public void before(Method method, Object[] args, Object obj) throws Throwable{
System.out.println(obj.getClass().getName() + "." + method.getName());
String clientName =(String) args[0];
System.out.println("How are you! Mr." + clientName +".");
}
}
Definition of Advisor:
public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor {
public boolean matches(Method method, Class clazz) {
return "greetTo".equals(method.getName());
}
public ClassFilter getClassFilter() {
return new ClassFilter() {
public boolean matches(Class clazz) {
return WaiterTest.class.isAssignableFrom(clazz);
}
};
}
}
Test Class:
public class TestGreetingBeforeAdvisor {
public static void main(String[] args) {
//method one: use by ProxyFactory
WaiterTest targetWaiterTest = new WaiterTest();
Seller targetSeller = new Seller();
GreetingBeforeAdvice advice = new GreetingBeforeAdvice();
GreetingAdvisor advisor = new GreetingAdvisor();
advisor.setAdvice(advice);
ProxyFactory pf = new ProxyFactory();
pf.setTarget(targetWaiterTest);
pf.addAdvisor(advisor);
pf.setOptimize(true);
WaiterTest proxy = (WaiterTest) pf.getProxy();
proxy.greetTo("John");
proxy.serveTo("Tom");
ProxyFactory pf1 = new ProxyFactory();
pf1.setTarget(targetSeller);
pf1.addAdvisor(advisor);
Seller seller = (Seller) pf1.getProxy();
seller.greetTo("John");
System.out.println("=============");
//method two:Spring xml,use ProxyFactoryBean
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
WaiterTest test = (WaiterTest) ctx.getBean("waiterTest");
test .greetTo("John");
test .serveTo("John");
}
}
Beans.xml:
<bean id="waiterTarget" class="com.xxx.springaop.advisor.WaiterTest"/>
<bean id="sellerTarget" class="com.xxx.springaop.advisor.Seller"/>
<bean id="greetingAdvice1" class="com.xxx.springaop.advisor.GreetingBeforeAdvice"/>
<bean id="greetingAdvisor" class="com.xxx.springaop.advisor.GreetingAdvisor"
p:advice-ref="greetingAdvice1"/>
<bean id="parent" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="greetingAdvisor"
p:proxyTargetClass="true"/>
<bean id="waiterTest" parent="parent" p:target-ref="waiterTarget"/>
<bean id="seller" parent="parent" p:target-ref="sellerTarget"/>
result:
com.xxx.springaop.advisor.WaiterTest.greetTo
How are you! Mr.John.
waiter greet to John...
waiter serving Tom...
seller greet to John...
=============
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy12 cannot be cast to com.xxx.springaop.advisor.WaiterTest
at com.xxx.springaop.advisor.TestGreetingBeforeAdvisor.main(TestGreetingBeforeAdvisor.java:48)
Summarize:
WaiterTest proxy = (WaiterTest) pf.getProxy(); //success
WaiterTest test = (WaiterTest) ctx.getBean("waiterTest");//fail,ClassCastException
Why?
I was not able to reproduce your problem, but I did some refactoring on your code, and this works just fine for me. Maybe it helps you as well at least as a starting point..
Waiter.java
public class Waiter {
public void greetTo(String name) {
System.out.println("waiter greet to " + name + "...");
}
public void serveTo(String name) {
System.out.println("waiter serving " + name + "...");
}
}
GreetingBeforeAdvice.java
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class GreetingBeforeAdvice implements MethodBeforeAdvice {
#Override
public void before(Method method, Object[] args, Object obj) throws Throwable {
String clientName = (String) args[0];
System.out.println("How are you! Mr." + clientName + ".");
}
}
GreetingAdvisor.java
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
import java.lang.reflect.Method;
public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor {
public boolean matches(Method method, Class clazz) {
return "greetTo".equals(method.getName());
}
public ClassFilter getClassFilter() {
return new ClassFilter() {
public boolean matches(Class clazz) {
return Waiter.class.isAssignableFrom(clazz);
}
};
}
}
beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="waiter" class="Waiter"/>
<!-- Advisor Configuration -->
<bean id="greetingAdvice" class="GreetingBeforeAdvice"/>
<bean id="greetingAdvisor" class="GreetingAdvisor">
<property name="advice" ref="greetingAdvice"/>
</bean>
<bean id="waiterProxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>greetingAdvisor</value>
</list>
</property>
<property name="target" ref="waiter"/>
</bean>
</beans>
and finally App.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
final Waiter waiter = (Waiter) ctx.getBean("waiterProxyFactory");
waiter.greetTo("Koray Tugay");
waiter.serveTo("Koray Tugay");
}
}
The output for me is as follows using Spring 4.3.12:
How are you! Mr.Koray Tugay.
waiter greet to Koray Tugay...
waiter serving Koray Tugay...
I would say you have not configured 'target' object in you ProxyFactoryBean definition. A proxy cannot be created if it does not have a target.

How to inject bean in a Tapestry service

I want to inject bean in a Tapestry service (not in a page).
For the moment, I use this :
public class EntityRealm extends AuthorizingRealm {
ApplicationContext ctx = new ClassPathXmlApplicationContext("/application-context-security.xml");
SecurityServices securityServices = (SecurityServices)ctx.getBean("securityServices");
It works, but I want use this :
public class EntityRealm extends AuthorizingRealm {
#Inject
private SecurityServices securityServices;
And my applicationContext is in the web.xml.
In this second case, the injection doesn't work. Why ?
AppModule.java :
public class AppModule
{
//#Resource(name = "realm")
#Inject
private static EntityRealm realm;
#Contribute(WebSecurityManager.class)
public static void addRealms(Configuration<EntityRealm> configuration) {
//EntityRealm realm = new EntityRealm();
configuration.add(realm);
}
public static void contributeFactoryDefaults( MappedConfiguration<String, Object> configuration)
{
configuration.override(SecuritySymbols.LOGIN_URL, "/login");
configuration.override(SecuritySymbols.UNAUTHORIZED_URL, "/login");
configuration.override(SecuritySymbols.SUCCESS_URL, "/index");
configuration.override(SymbolConstants.APPLICATION_VERSION, "2.0-SNAPSHOT");
}
public static void contributeApplicationDefaults(MappedConfiguration<String, Object> configuration)
{
configuration.add(SymbolConstants.HMAC_PASSPHRASE, new BigInteger(130, new SecureRandom()).toString(32));
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en,fr");
configuration.add( "tapestry.default-cookie-max-age", "31536000" );
}
public RequestFilter buildTimingFilter(final Logger log)
{
return new RequestFilter()
{
public boolean service(Request request, Response response, RequestHandler handler)
throws IOException
{
long startTime = System.currentTimeMillis();
try
{
return handler.service(request, response);
} finally
{
long elapsed = System.currentTimeMillis() - startTime;
log.info(String.format("Request time: %d ms", elapsed));
}
}
};
}
public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
#Local
RequestFilter filter)
{
configuration.add("Timing", filter);
}
}
And the EntityRealm.java :
public class EntityRealm extends AuthorizingRealm {
//***************************************
//************* Attributes *************
//***************************************
//ApplicationContext ctx = new ClassPathXmlApplicationContext("/application-context-security.xml");
//SecurityServices securityServices = (SecurityServices)ctx.getBean("securityServices");
//#Resource(name = "securityServices")
#Inject
private SecurityServices securityServices;
//***************************************
//************ Constructors *************
//***************************************
public EntityRealm() {
super(new MemoryConstrainedCacheManager());
setName("myapprealm");
setAuthenticationTokenClass(UsernamePasswordToken.class);
}
//***************************************
//********** Public Methods *************
//***************************************
#Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
if (principals == null) throw new AuthorizationException("PrincipalCollection was null, which should not happen");
application-context.xml :
<bean id="realm" class="net.atos.m2m.telecom.ihm.services.EntityRealm">
<property name="securityServices" ref="securityServices"></property>
</bean>
<bean id="securityServices" class="net.atos.m2m.telecom.ihm.applicatif.services.security.impl.SecurityServicesImpl">
<property name="servicesTelSecu" ref="servicesTelSecu"></property>
<property name="converterSecDSPtoDTO" ref="converterSecDSPtoDTO"></property>
<property name="converterSecDTOtoDSP" ref="converterSecDTOtoDSP"></property>
</bean>
Can you help me ?
Thank you.
How i say in previous comment, if you create EntityRealm in this way .. new EntityRealm() the inject\autowire does not work.
You must define EntityRealm as bean .. XML or Annotation.
<bean id="entityRealm" class="package.EntityRealm"/>
<bean id="securityServices" class="package.SecurityServices"/>
You can use #Resource instead,
#Resource(name = "securityServices")
private SecurityServices securityServices;
And make sure that application-context-security.xml file is loaded by Spring.

UsernameTokenValidator Can not #Autowired Dao

I have a Spring-ws and i am using Apahce-wss4j for spring-ws authentication. I want to use my Dao class in my custom TokenValidator class. But there was an exception can not #Autowired my Dao class. Here is my code
applicationContext.xml
<bean id="myWssConfig" class="tr.com.xxx.services.MyWssConfig"/>
<bean id="kepDBDAO" class="tr.com.xxx.dao.KepDBDAOImpl"/>
<bean id="ssha" class="tr.com.xxx.utils.SSHA"/>
<bean id="memberStatusService" class="tr.com.xxx.services.MemberStatusServiceImpl"/>
<bean id="myUsernameTokenValidator" class="tr.com.xxx.services.MyUsernameTokenValidator">
<property name="kepDBDAO" ref="kepDBDAO"/>
</bean>
<sws:interceptors>
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="validationActions" value="UsernameToken"/>
<property name="validationCallbackHandler" ref="callbackHandler"/>
<property name="wssConfig">
<ref bean="myWssConfig"/>
</property>
</bean>
</sws:interceptors>
Here is MyWssConfig.java
#Component("myWssConfig")
public class MyWssConfig extends WSSConfig {
public MyWssConfig() {
setValidator(WSSecurityEngine.USERNAME_TOKEN, MyUsernameTokenValidator.class);
setRequiredPasswordType(WSConstants.PASSWORD_TEXT);
}
}
And here is MyUsernameTokenValidator.java
#Component
public class MyUsernameTokenValidator extends UsernameTokenValidator {
private static final Logger LOGGER = LoggerFactory
.getLogger(MyUsernameTokenValidator.class);
#Autowired
private KepDBDAO kepDBDAO;
#Transactional
protected void verifyPlaintextPassword(UsernameToken usernameToken, RequestData data) throws WSSecurityException {
if (usernameToken != null && usernameToken.getPassword() != null) {
byte[] saltValue = null;
kepDBDAO.getWsUsers("basvuru");
String hashPassword = null;
try {
hashPassword = SSHA.calculateSSHA256(saltValue, usernameToken.getPassword());
} catch (NoSuchAlgorithmException e) {
LOGGER.error(e.toString(), e);
} catch (IOException e) {
LOGGER.error(e.toString(), e);
}
usernameToken.setPassword(hashPassword);
super.verifyDigestPassword(usernameToken, data);
}
}
public KepDBDAO getKepDBDAO() {
return kepDBDAO;
}
public void setKepDBDAO(KepDBDAO kepDBDAO) {
this.kepDBDAO = kepDBDAO;
}
}
Couldn't #Autowired my KepDBDAO when I call webservice in SOAPUI.
Help me please.. THank you all guys.
Try this:
1. In applicationContext:
<context:component-scan base-package="tr.com.xxx.dao"/>
<context:component-scan base-package="package for MyUsernameTokenValidator"/>
remove these beans:
kepDBDAO, myUsernameTokenValidator
2. Remove setter and getter for KepDBDAO in MyUsernameTokenValidator
3. Make sure KepDBDAOImpl is marked as #Service
I solved my problem.
#Component("myWssConfig")
public class MyWssConfig extends WSSConfig {
#Autowired
private MyUsernameTokenValidator myUsernameTokenValidator;
//
#PostConstruct
public void myInit() {
setValidator(WSSecurityEngine.USERNAME_TOKEN, myUsernameTokenValidator);
setRequiredPasswordType(WSConstants.PASSWORD_TEXT);
}
}

How to change XML-based Configuration to annotation configuration in Spring?

The class is as following:
class ReportControllerBase {
String reportName = "Report";
public String getReportName() {
return reportName;
}
public void setReportName(String reportName) {
this.reportName = reportName;
}
// ...
}
class AnnualReportController extends ReportControllerBase {
// ...
}
class SkinCareAnnualReprotController extends AnnualReportController {
String productName;
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
}
And the XML-based configuration is as following:
<bean id="annualReportController" class="AnnualReportController">
<property name="reportName" value="Annual Report"/>
</bean>
<bean id="annualSpecialReportController" class="AnnualReportController">
<property name="reportName" value="Annual Special Report"/>
</bean>
<bean id="skinCareAnnualReprotController" class="SkinCareAnnualReprotController" parent="annualReportController">
<property name="productName" value="A famous skin care product"/>
</bean>
The Bean annualReportController and annualSpecialReportController is the instance of the same Class. And skinCareAnnualReprotController is inherited from bean annualReportController.
How to implement this configuration in annotation-based configuration in Spring?
#Configuration
public class ReportConfiguration {
#Bean public AnnualReportController annualReportController() {
AnnualReportController annualReportController = new AnnualReportController();
annualReportController.setReportName("Annual Report");
return annualReportController;
}
#Bean public AnnualReportController annualSpecialReportController() {
AnnualReportController annualSpecialReportController = new AnnualReportController();
return withAnnualSpecialReportName(annualSpecialReportController);
}
#Bean public SkinCareAnnualReportController skinCareAnnualReportController() {
SkinCareAnnualReportController skinCareAnnualReportController = new SkinCareAnnualReportController();
skinCareAnnualReportController.setProductName("A famous skin care product");
return withAnnualSpecialReportName(skinCareAnnualReportController);
}
// in this instance, a helper method is arguably overkill,
// but I've included it for demonstration
private <T extends AnnualReportController> T withAnnualSpecialReportName(T report) {
report.setReportName("Annual Special Report");
return report;
}
}
Take a look at the Spring 3.1 documentation for more information.

How to test the destruction of session scoped beans in jUnit?

I have a session scoped bean in which I hold some user data and want to write a unit test to ensure that it remains session scoped.
I want to mock the starting and the ending of a session in jUnit and compare the values of the session scoped bean.
For now I have the following (rough drafts) of the unit test:
I use a custom context loader to register the session scope.
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.test.context.support.GenericXmlContextLoader;
import org.springframework.web.context.request.SessionScope;
public class SessionScopedGenericXmlContextLoader extends GenericXmlContextLoader {
#Override
protected void customizeBeanFactory(final DefaultListableBeanFactory beanFactory) {
beanFactory.registerScope("session", new SessionScope());
super.customizeBeanFactory(beanFactory);
}
}
The unit test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = SessionScopedGenericXmlContextLoader.class,
locations = { "classpath:/test-applicationContext.xml","classpath:/cache-config.xml" })
public class CachingTest extends AbstractJUnit4SpringContextTests {
// Session scoping
protected MockHttpSession session;
protected MockHttpServletRequest request;
ApplicationContext ctx;
CacheManager cacheManager;
Cache accountSettingsCache;
#Autowired
#Qualifier("cachedMethods")
DummyCacheMethods methods;
#Autowired
private SecurityContextHolder contextHolder;
protected void startRequest() {
request = new MockHttpServletRequest();
request.setSession(session);
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
}
protected void endRequest() {
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
RequestContextHolder.resetRequestAttributes();
request = null;
}
protected void startSession() {
session = new MockHttpSession();
}
protected void endSession() {
session.clearAttributes();
session = null;
}
#Before
public void constructSession() {
ctx = applicationContext;
cacheManager = (CacheManager) ctx.getBean("cacheManager");
accountSettingsCache = cacheManager.getCache("accountSettingsCache");
startRequest();
startSession();
}
#After
public void sessionClean() {
endRequest();
endSession();
contextHolder.clearContext();
}
#Test
// #DirtiesContext
public void checkSession1() {
final Authentication authentication = new Authentication() {
public String getName() {
return "Johny";
}
public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
}
public boolean isAuthenticated() {
return true;
}
public Object getPrincipal() {
final CustomUserDetails pr = new CustomUserDetails();
pr.setUsername("Johny");
return pr;
}
public Object getDetails() {
return null;
}
public Object getCredentials() {
return null;
}
public Collection<GrantedAuthority> getAuthorities() {
return null;
}
};
contextHolder.getContext().setAuthentication(authentication);
assertTrue(methods.getCurrentUserName().equals(accountSettingsCache.get("currentUser").get()));
assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication.getPrincipal()).getUsername()));
}
#Test
// #DirtiesContext
public void testSession2() {
final Authentication authentication2 = new Authentication() {
public String getName() {
return "James";
}
public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
}
public boolean isAuthenticated() {
return true;
}
public Object getPrincipal() {
final CustomUserDetails pr = new CustomUserDetails();
pr.setUsername("James");
return pr;
}
public Object getDetails() {
return null;
}
public Object getCredentials() {
return null;
}
public Collection<GrantedAuthority> getAuthorities() {
return null;
}
};
SecurityContextHolder.setContext(contextHolder.getContext());
SecurityContextHolder.clearContext();
SecurityContextHolder.getContext().setAuthentication(authentication2);
assertTrue(methods.getCurrentUserName().equals(accountSettingsCache.get("currentUser").get()));
assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication2.getPrincipal()).getUsername()));
}
#Test
public void testWiring() {
assertTrue("cacheManager is null", cacheManager != null);
assertTrue("accountSettingsCache is null", accountSettingsCache != null);
}
}
And the relevant function from DummyCachedMethods is:
#Cacheable(value = { "accountSettingsCache" }, key = "new String(\"currentUser\")")
public String getCurrentUserName() {
return WebUtils.getCurrentUser().getUsername();
}
WebUtils.getCurrentUser() just returns the current Principal from the SecurityContext.
But this does not work, the test does not pass at this line:
assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication2.getPrincipal()).getUsername()));
Since the method call is cached, it still returns Johnny instead of James.
My cache related beans are:
<bean id="accountSettingsCache" class="org.springframework.cache.concurrent.ConcurrentMapCache" scope="session">
<constructor-arg>
<value>accountSettingsCache</value>
</constructor-arg>
<aop:scoped-proxy proxy-target-class="false" />
</bean>
<bean id="defaultCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="defaultCache" />
<bean id="cacheManager" class="my.package.DynamicCacheManager" scope="session">
<property name="caches">
<set>
<ref bean="accountSettingsCache" />
<ref bean="defaultCache" />
</set>
</property>
<aop:scoped-proxy />
</bean>
accountSettingsCache is session scoped, I want to start a new session and destroy it.
It does pass if I uncomment the DirtiesContext annotations, but I guess it's not what I want.
What am I missing ?

Resources