在常见的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容器中