@Component Spring注解解读以及内部原理

您所在的位置:网站首页 compent注解 @Component Spring注解解读以及内部原理

@Component Spring注解解读以及内部原理

#@Component Spring注解解读以及内部原理| 来源: 网络整理| 查看: 265

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