1.环境搭建
基于注解形式配置spring
因为我是从spring官网下载了源码允许的,所以jar包省略不写了。
1.1新建配置类
@Configuration
@ComponentScan("com.st")
public class Appconfig {
}
1.2新建dao
@Repository
public class Indexdao implements ApplicationContextAware {
private ApplicationContext applicationContext;
public Indexdao() {
System.out.println("construtor");
}
@PostConstruct
public void init(){
System.out.println("inint");
}
public void query() {
System.out.println("12");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("ApplicationContext applicationContext");
}
}
1.3新建测试类
public class Test {
public static void main(String[] args) {
//使用默认的构造方法一定要在最后refresh
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Appconfig.class);
//context.refresh();
context.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
context.refresh();
Indexdao indexdao = context.getBean(Indexdao.class);
Indexdao indexdao1 = context.getBean(Indexdao.class);
indexdao.query();
System.out.println(indexdao.hashCode()+"-------"+indexdao1.hashCode());
}
}
2.AnnotationConfigApplicationContext 创建对象的时候spring都干了什么?
2.1 AnnotationConfigApplicationContext默认构造方法
public AnnotationConfigApplicationContext() {
/**
* 这个类是一个reader,一个读取器
* 读取一个被加了注释的bean
* 这个类在构造方法中实例化
*/
private final AnnotatedBeanDefinitionReader reader;
/**
* 扫描器,扫描所有加了注解的bean
* 但是实际上我们扫描包不是用的scanner这个对象
* 是Spring自己new的一个ClassPathBeanDefinitionScanner
* 这里的scanner仅仅是为了让我们能从外部调用AnnotationConfigApplicationContext的scanner方法
* 同样是在构造方法中被实例化
*/
private final ClassPathBeanDefinitionScanner scanner;
//这里的this为当前类也就是AnnotationConfigApplicationContext,所以这个类也可以当作一个BeanDefinitionRegistry
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
2.2 AnnotationConfigApplicationContext(Class<?>… annotatedClasses)构造方法
一般我们都会这么写,直接在构造方法中写入我们的配置类
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//这里由于他有父类,故而会先调用父类的构造方法,然后才会调用自己的构造方法
//在默认的构造方法中初始一个读取器和扫描器
this();
register(annotatedClasses);
refresh();
}
2.3 看一下AnnotatedBeanDefinitionReader都做了什么
跟进AnnotatedBeanDefinitionReader的构造方法
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
//getOrCreateEnvironment()给当前的registry创建个环境
this(registry, getOrCreateEnvironment(registry));
}
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);
}
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
//真正的注册
registerAnnotationConfigProcessors(registry, null);
}
就是这里提供的后置处理器为spring扫描注册bean提供了强大的支持
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//返回beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//AnnotationAwareOrderComparator 能解析@Order注解和Priority
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//提供了延迟加载的功能
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//往BeanDefinitionMap中注册spring内部的基础类
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//ConfigurationClassPostProcessor 实现的BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor 这个类很重要,之后会提到
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
此时beanFactory中就会插入这几个基础的工具类
registerPostProcessor()其实就是调用 DefaultListableBeanFactory的registerBeanDefinition()方法往容器的beanMap中加入当前的bean
BeanDefinitionHolder 和BeanDefinition没太大的区别就是存了BeanDefinition还有他的别名和beanName
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
调用
2.4简单介绍后置处理器的作用
后置处理器可以粗略的分为BeanPostProcessor和BeanFactoryPostProcessor
创建一个BeanPostProcessor
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("indexdao")){
System.out.println("before process" );
}
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("indexdao")){
System.out.println("after process" );
}
return null;
}
}
可以看到,在容器创建之后,调用了beanPostProcessor的before,after方法
这样spring使用后置处理器就可以在bean创建之前对bean进行一些特殊处理
2.5ClassPathBeanDefinitionScanner将指定包下的类通过一定规则过滤后 将Class 信息包装成 BeanDefinition 的形式注册到IOC容器中
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment) {
//registry instanceof ResourceLoader 当前的registry是AnnotationConfigApplicationContext实现了ResourceLoader 接口
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
ResourceLoader 提供了默认的classpath:*/
public interface ResourceLoader {
/** Pseudo URL prefix for loading from the class path: "classpath:" */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
Resource getResource(String location);
@Nullable
ClassLoader getClassLoader();
}
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
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
这里插入了扫描的基本信息如果配置了include 和exclude就会在这里设置进去
3.AbstractApplicationContext的refresh方法
3.1prepareRefresh初始化属性源(property,source配置)
protected void prepareRefresh() {
//准备工作包括设置启动时间,是否激活标识位
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment.
//留给子类实现的方法
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
3.2 obtainFreshBeanFactory
利用注解的配置类这里很简单直接返回beanFactory,用web.xml会比较复杂
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
3.3prepareBeanFactory(beanFactory)
准备工厂
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
//bean表达式解析器,能够获取bean中的属性
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//对象与string类型的转换 <property red="dao">
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//添加一个后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//添加自动注入忽略的列表,继承以下类自动注入时会忽略
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
/**
* 如果自定义的bean中没有名为systemProperties,systemEnvironment,environment的bean则注册
* bean key为‘systemEnvironment’,‘environment’ 和‘systemProperties’
* 这两个bean就是一些系统配置和系统环境信息
*/
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
总结
1.容器创建初期创建了两个对象 xxreader和scanner 并在beanMap中加入了6个对象,为后续操作提供支持。需要关注ConfigurationClassPostProcessor比较重要和特殊。
2.后置处理器是spring的强大之处,可以插手bean的创建。