spring4引入新註解@Conditional,可使用在Bean註解的類和方法上。java
示例:spring
@Service("loginService") @Conditional(value = LoginServiceCondition.class) public class MockLoginServiceImpl implements LoginService{ private static Logger logger = LoggerFactory.getLogger(MockLoginServiceImpl.class); @Override public BaseResult validateUserLogin(User user) { logger.info("[MOCK數據]"); BaseResult result = new BaseResult(); result.setSuccess(Boolean.FALSE); return result; } @Override public BaseResult regeditUser(User user) { return null; } }
如上 @Conditional(value = LoginServiceCondition.class),就能夠經過LoginServiceCondition這個類進行判斷是否加載這個bean。ide
@Retention(RetentionPolicy.RUNTIME) @Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD}) public @interface Conditional { public abstract Class<? extends Condition>[] value(); }
經過spring源碼能夠看出能夠支持多個類進行判斷。code
public class LoginServiceCondition implements Condition{ @SuppressWarnings("unused") @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata anno) { //獲取環境變量 Environment env = context.getEnvironment(); //檢查bean定義 BeanDefinitionRegistry beanDefinitionRegistry = context.getRegistry(); //檢查bean是否存在 ConfigurableListableBeanFactory configurableListableBeanFactory = context.getBeanFactory(); //獲取ResourceLoader所加載的資源 ResourceLoader resourceLoader =context.getResourceLoader(); //檢查ClassLoader加載並檢查類是否存在 ClassLoader classLoader = context.getClassLoader(); //判斷bean是否還有其餘註解 boolean isHaveOtherAnno = anno.isAnnotated("service"); //獲取特定類型註解的屬性 Map<String, Object> map1 = anno.getAnnotationAttributes("name"); Map<String, Object> map2 = anno.getAnnotationAttributes("name", false); MultiValueMap<String, Object> map3 = anno.getAllAnnotationAttributes("name"); MultiValueMap<String, Object> map4 = anno.getAllAnnotationAttributes("name", false); return !env.containsProperty("mock"); } }
能夠發現,註解中的value配置的爲這個類,實現了org.springframework.context.annotation.Condition這個接口,該接口中只有一個方法matches,經過這個方法返回boolean的值判斷@conditional是否生效。接口
注:@Profile的實現也是經過Conditional註解實現,源碼以下:資源
@Retention(RetentionPolicy.RUNTIME) @Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD}) @Documented @Conditional({ProfileCondition.class}) public @interface Profile { public abstract String[] value(); } /** 激活profile的判斷類 **/ class ProfileCondition implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { if (context.getEnvironment() != null) { MultiValueMap attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); if (attrs != null) { for (Iterator localIterator = ((List) attrs.get("value")).iterator(); localIterator.hasNext();) { Object value = localIterator.next(); if (context.getEnvironment().acceptsProfiles((String[]) (String[]) value)) { return true; } } return false; } } return true; } }