spring 容器为什么能够解析注解需要干的事情

在常见的spring使用的项目中,我们经常大量使用到注解如:@Autowired、@Component、@Bean等这些注解的。

从之前的spring容器启动(2.1.6版本)过程中,知道spring加载bean的工厂主要是在ConfigurableApplicationContext是实现类AnnotationConfigApplicationContext中的 beanFactory (AnnotationConfigApplicationContext 的父类GenericApplicationContext

)工厂的属性进行bean的加载的。

而当spring通过注解annotation 进行加载各个bean时,是需要要一个注解的解析器来解释各个注解的含义与作用的,因此通过解析器将被注解的各个方法或者类进行处理,并将bean注入到容器(spring context)中。

而spring context在加载注解的解析器是何时呢?

下面通过bebug调试看

上面发现在还没有通过createApplicationContext()方法进行创建应用的上下文(容器)context时,context还是null的,继续往下调试发现

当使用createApplicationContext()初始化容器后,context的beanFactory就被初始化话,而且也加载了部分的注解的解释器(***Processor)

在createApplicationContext()方法的最后看到BeanUtils.instantiateClass()进行容器对象的实例化的。

protected ConfigurableApplicationContext createApplicationContext() {
	...
	...
	...
	return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}

再看AnnotationConfigApplicationContext构造方法可得知this.reader = new AnnotatedBeanDefinitionReader(this); 进行了注解解析器的加载,继续debug进入看。

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

	...
	...
	...

	/**
	 * Create a new AnnotationConfigApplicationContext that needs to be populated
	 * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
	 */
	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

	...
	...
	...

}
public class AnnotatedBeanDefinitionReader {

	...
	...
	...

	/**
	 * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
	 * the given {@link Environment}.
	 * @param registry the {@code BeanFactory} to load bean definitions into,
	 * in the form of a {@code BeanDefinitionRegistry}
	 * @param environment the {@code Environment} to use when evaluating bean definition
	 * profiles.
	 * @since 3.1
	 */
	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

	...
	...
	...

}

当执行AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);完成才加载完成了注解的解释器

最终在Context的beanFactory的beanPostProcessors中可以看到有项目中所用到的注解的解释器,其中BeeXxlJobAnnotationBeanFactory是我自定义注解的解释器


import com.***.bee.job.annotation.BeeXxlJob;
import com.***.bee.job.handler.BaseXxlMethodJobHandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import com.xxl.job.core.handler.IJobHandler;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class BeeXxlJobAnnotationBeanFactory implements BeanPostProcessor {
    private static Logger logger = LoggerFactory.getLogger(BeeXxlJobAnnotationBeanFactory.class);

    public BeeXxlJobAnnotationBeanFactory() {
    }

    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
      =
    }
}

其核心原理是实现了beanPostProcessor接口,spring在进行加载注解解释器的时候,会通过Java中的SPI原理来加载beanPostProcessor接口的所有实现类,将自定义注解的解析加入到spring容器中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值