@SuppressWarnings("unchecked")
	@Override
	public <T> T getAttributeValue(String attributeName, Class<T> attributeType, Collection<? extends SynthesizedAnnotation> synthesizedAnnotations) {
		Object value = valueCaches.get(attributeName, attributeType);
		if (Objects.isNull(value)) {
			synchronized (valueCaches) {
				value = valueCaches.get(attributeName, attributeType);
				if (Objects.isNull(value)) {
					value = synthesizedAnnotations.stream()
						.filter(ma -> ma.hasAttribute(attributeName, attributeType))
						.min(annotationComparator)
						.map(ma -> ma.getAttributeValue(attributeName))
						.orElse(null);
					valueCaches.put(attributeName, attributeType, value);
				}
			}
		}
		return (T)value;
	}
@Test
	public void getAttributeValueTest() {
		CacheableSynthesizedAnnotationAttributeProcessor processor = new CacheableSynthesizedAnnotationAttributeProcessor();

		Map<String, Object> values1 = MapBuilder.<String, Object> create().put("name", "name1").put("value", 111).build();
		SynthesizedAnnotation annotation1 = new TestSynthesizedAnnotation(1, 0, values1);
		Map<String, Object> values2 = MapBuilder.<String, Object> create().put("name", "name2").put("value", "value2").build();
		SynthesizedAnnotation annotation2 = new TestSynthesizedAnnotation(0, 0, values2);

		assertEquals("name2", processor.getAttributeValue("name", String.class, Arrays.asList(annotation1, annotation2)));
		assertEquals(Integer.valueOf(111), processor.getAttributeValue("value", Integer.class, Arrays.asList(annotation1, annotation2)));
	}