spring註解之@conditional

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;
	}
}
相關文章
相關標籤/搜索