2013年1月8日 星期二

<context:annotation-config/>與<context:component-scan/>的API

如果使用context namespace設定啟用annotation,則Spring會自動scan出有@Component、@Repository、@Service、@Controller等class並放到container中,那麼這底層的API是哪一個呢?
答案是:org.springframework.context.annotation.ClassPathBeanDefinitionScanner
若我們要自己implement類似的功能,但是不需要把掃出來的class放到Spring Container中,可以使用org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
事實上org.springframework.context.annotation.ClassPathBeanDefinitionScanner是繼承org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider的。

以下範例是繼承ClassPathScanningCandidateComponentProvider後要掃出所有具@MountPage的classes。
代碼:
import java.util.LinkedHashSet;
import java.util.Set;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;

public class MountPageScanner extends ClassPathScanningCandidateComponentProvider {

    public MountPageScanner() {
        super(false);
        addIncludeFilter(new AnnotationTypeFilter(MountPage.class));
    }

    public Set<BeanDefinition> findCandidateComponents(String... basePackages) {
        Set<BeanDefinition> beans = new LinkedHashSet<BeanDefinition>();
        for (String basePackage : basePackages) {
            beans.addAll(findCandidateComponents(basePackage));
        }
        return beans;
    }
}