SEC-2066: ProtectPointcutPostProcessor is now ThreadSafe
Previously a ConcurrentModificationException could occur when PointcutExpression.matchesMethodExecution was performed in multiple threads. Another issue was that beans may get processed multiple times. Now a lock is performed to ensure that only a single thread has access to PointcutExpression.matchesMethodExecution and that each bean only gets processed once.
This commit is contained in:
parent
51fd83060e
commit
1a7aaa85c4
|
@ -51,6 +51,7 @@ final class ProtectPointcutPostProcessor implements BeanPostProcessor {
|
|||
private final PointcutParser parser;
|
||||
private final Set<String> processedBeans = new HashSet<String>();
|
||||
|
||||
|
||||
public ProtectPointcutPostProcessor(MapBasedMethodSecurityMetadataSource mapBasedMethodSecurityMetadataSource) {
|
||||
Assert.notNull(mapBasedMethodSecurityMetadataSource, "MapBasedMethodSecurityMetadataSource to populate is required");
|
||||
this.mapBasedMethodSecurityMetadataSource = mapBasedMethodSecurityMetadataSource;
|
||||
|
@ -80,26 +81,34 @@ final class ProtectPointcutPostProcessor implements BeanPostProcessor {
|
|||
return bean;
|
||||
}
|
||||
|
||||
// Obtain methods for the present bean
|
||||
Method[] methods;
|
||||
try {
|
||||
methods = bean.getClass().getMethods();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
synchronized(processedBeans) {
|
||||
// check again synchronized this time
|
||||
if (processedBeans.contains(beanName)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
// Check to see if any of those methods are compatible with our pointcut expressions
|
||||
for (Method method : methods) {
|
||||
for (PointcutExpression expression : pointCutExpressions) {
|
||||
// Try for the bean class directly
|
||||
if (attemptMatch(bean.getClass(), method, expression, beanName)) {
|
||||
// We've found the first expression that matches this method, so move onto the next method now
|
||||
break; // the "while" loop, not the "for" loop
|
||||
// Obtain methods for the present bean
|
||||
Method[] methods;
|
||||
try {
|
||||
methods = bean.getClass().getMethods();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
|
||||
// Check to see if any of those methods are compatible with our pointcut expressions
|
||||
for (Method method : methods) {
|
||||
for (PointcutExpression expression : pointCutExpressions) {
|
||||
// Try for the bean class directly
|
||||
if (attemptMatch(bean.getClass(), method, expression, beanName)) {
|
||||
// We've found the first expression that matches this method, so move onto the next method now
|
||||
break; // the "while" loop, not the "for" loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processedBeans.add(beanName);
|
||||
}
|
||||
|
||||
processedBeans.add(beanName);
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue