spring4引入新注解@Conditional,可以使用在Bean注解的类和方法上。
示例:
@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。
@Retention(RetentionPolicy.RUNTIME)@Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD})public @interface Conditional{ public abstract Class [] value();}
通过spring源码可以看出可以支持多个类进行判断。
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"); //获取特定类型注解的属性 Mapmap1 = anno.getAnnotationAttributes("name"); Map map2 = anno.getAnnotationAttributes("name", false); MultiValueMap map3 = anno.getAllAnnotationAttributes("name"); MultiValueMap 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; }}