@Component Spring注解解读以及内部原理 |
您所在的位置:网站首页 › compent注解 › @Component Spring注解解读以及内部原理 |
1. Component
@Component
使用此注解会被Spring加载到IOC容器中
2. ComponentScan
@ComponentScan
扫描带 @Component 注解
3 注解的派生性
@Service
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
@Controller
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
@Configuration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
/**
* Explicitly specify the name of the Spring bean definition associated with the
* {@code @Configuration} class. If left unspecified (the common case), a bean
* name will be automatically generated.
* The custom name applies only if the {@code @Configuration} class is picked * up via component scanning or supplied directly to an * {@link AnnotationConfigApplicationContext}. If the {@code @Configuration} class * is registered as a traditional XML bean definition, the name/id of the bean * element will take precedence. * @return the explicit component name, if any (or empty String otherwise) * @see AnnotationBeanNameGenerator */ @AliasFor(annotation = Component.class) String value() default ""; } @Respositry 此三个注解以及相关注解内部实现了@Component, 因此它们具有Component的特性会被加载到Spring IOC容器中,它们对于Spring在物理存储是没有区别的,都属于IOC容器的Bean。 4. 内部原理 Spring加载@Component实现原理 首先我们看看Spring程序的入口 public class SpringAnnotationDemo { public static void main(String[] args) { //创建Spring Context上下文 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); } }现在绝大部分的上下文都是Annotation上下文,我们观察一下AnnotationConfigApplicationContext,构造方法 public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry { private final AnnotatedBeanDefinitionReader reader; private final ClassPathBeanDefinitionScanner scanner; /** * Create a new AnnotationConfigApplicationContext that needs to be populated * through {@link #register} calls and then manually {@linkplain #refresh refreshed}. */ public AnnotationConfigApplicationContext() { //AnnotatedBeanDefinitionReader是一个读取注解的Bean读取器,这里将this传了进去。 this.reader = new AnnotatedBeanDefinitionReader(this); //扫描注解真正的核心再此 this.scanner = new ClassPathBeanDefinitionScanner(this); } .... }1.构造AnnotationConfigApplicationContext对象时,同事初始化IOC容器,其实是调用父(GenericApplicationContext)构造方法。IOC容器在这里初始化 2.构造一个reader解析Bean使用的解析器。此处我们不重点关注此类。scanner继承 ClassPathScanningCandidateComponentProvider 我们重点关注此方法 ClassPathBeanDefinitionScanner()构造方法 public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { //我们要使用的类过滤 registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }registerDefaultFilters();是我们重点关注的方法,属于Scanner成员变量构造函数一个方法 /** * Register the default filter for {@link Component @Component}. *This will implicitly register all annotations that have the * {@link Component @Component} meta-annotation including the * {@link Repository @Repository}, {@link Service @Service}, and * {@link Controller @Controller} stereotype annotations. * Also supports Java EE 6's {@link javax.annotation.ManagedBean} and * JSR-330's {@link javax.inject.Named} annotations, if available. * */ @SuppressWarnings("unchecked") protected void registerDefaultFilters() { this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter( ((Class |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |