1.spring简单demo
目录结构
AppConfig
@Configuration
@ComponentScan("com.xiayu")
public class AppConfig {
}
CityService
@Service("cityService")
public class CityService {
}
SpringDemoApplication
package com.xiayu;
import com.xiayu.config.AppConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringDemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
Object cityService = annotationConfigApplicationContext.getBean("cityService");
System.out.println(cityService.getClass());
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xiayu</groupId>
<artifactId>springdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.0.RELEASE</version>
</dependency>
</dependencies>
</project>
结果
2.分析源码
//容器初始化
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//核心步骤是调用AnnotationConfigApplicationContext的父类GenericApplicationContext的构造方法
this();
//将配置类的beanDefinition put入到DefaultListableBeanFactory类中的beanDefinitionMap中
//this.beanDefinitionMap.put(beanName, beanDefinition);
register(annotatedClasses);
//spring framework的核心方法,一共包含12个步骤
refresh();
}
GenericApplicationContext类构造方法
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
//DefaultListableBeanFactory类为抽象类,该类
/**
* DefaultListableBeanFactory类官方描述,该类是ConfigurableListableBeanFactory和BeanDefinitionRegistry类的默认实现类,此处使用了模版模式,该类主要提供类的BeanDefinition信息,将类的定义信息放置于beanDefinitionMap中,类的名称作为key
* Spring's default implementation of the {@link ConfigurableListableBeanFactory}
* and {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory
* based on bean definition metadata, extensible through post-processors.
**/
/** Map of bean definition objects, keyed by bean name.
* private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
**/
}
refresh()方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//设置启动时间,是否激活标识位,初始化属性源(property source)配置
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//在spring的环境中去执行已经被注册的factory processors,
//设置执行自定义的ProcessBeanFactory和spring内部自定义的
//扫描出所有的类到DefaultListableBeanFactory类的beanDefinitionMap中,然后调用beanFactoryPostProcessor方法,该方法可以是自我定义的,也可以由spring中定义的
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩余的非懒加载的单例,并将其放入单例池中SingletonObjects
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
一个类在BeanDefinition中的信息
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
public static final String SCOPE_DEFAULT = ""; //默认作用范围
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; //自动注入
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; //依据名称自动注入
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; //依据类型自动注入
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR; //构造参数中自动注入
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
public static final int DEPENDENCY_CHECK_NONE = 0;
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
public static final int DEPENDENCY_CHECK_ALL = 3;
public static final String INFER_METHOD = "(inferred)";
private volatile Object beanClass; //beanClass name
private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false; //是否是抽象类
private boolean lazyInit = false; //是否是懒加载
private int autowireMode = AUTOWIRE_NO; //自动注入模式
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
private String[] dependsOn; //依赖
private boolean autowireCandidate = true;
private boolean primary = false; //是否是primary
private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>(); //依据名称自动注入的名称
private Supplier<?> instanceSupplier;
private boolean nonPublicAccessAllowed = true; //不可public访问
private boolean lenientConstructorResolution = true; //
private String factoryBeanName; //工厂bean名称
private String factoryMethodName; //工厂方法
private ConstructorArgumentValues constructorArgumentValues; //构造器参数
private MutablePropertyValues propertyValues;
private MethodOverrides methodOverrides;
private String initMethodName;
private String destroyMethodName;
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
private boolean synthetic = false;
private int role = BeanDefinition.ROLE_APPLICATION;
private String description; //描述信息
private Resource resource;
protected AbstractBeanDefinition() {
this(null, null);
}
protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) {
this.constructorArgumentValues = cargs;
this.propertyValues = pvs;
}
protected AbstractBeanDefinition(BeanDefinition original) {
setParentName(original.getParentName());
setBeanClassName(original.getBeanClassName());
setScope(original.getScope());
setAbstract(original.isAbstract());
setLazyInit(original.isLazyInit());
setFactoryBeanName(original.getFactoryBeanName());
setFactoryMethodName(original.getFactoryMethodName());
setRole(original.getRole());
setSource(original.getSource());
copyAttributesFrom(original);
}
}
下图为CityService类的BeanDefinition信息
(图片上传不上去)
BeanFactoryPostProcessor接口
通过调试,可以发现ConfigurableListableBeanFactory工厂中BeanDefinitionMap中已经有beanDefinition信息了。
finishBeanFactoryInitialization(beanFactory);实例化对象
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//真正进行实例化操作,具体实现在DefaultListableBeanFactory类中
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons();方法
beanDefinitionNames为所有类的bean name信息,可根据其获取到对应的BeanDefinition类信息,然后依据BeanDefinition信息进行bean的实例化。在实例化中,首先进行判断是否是FactoryBean。
循环依赖
@Service
public class ServiceA{
@Autowired
private ServiceB serviceB;
}
@Service
public class ServicB{
@Autowired
private ServiceA serviceA;
}
//bean和对象的区别
bean在spring中有完整的生命周期,在bean创建前后都可以处理一些事情,还有liftcyclecallback事件,aop,自动注入等等,而对象就是new 出来一个对象。
//循环依赖
上例子中ServiceA和ServiceB互相自动注入,spring是怎么进行初始化bean?
spring支持循环依赖,但bean必须是单例的。spring中有一个bean创建中的列表,在生成bean的过程中的时候会将该bean的名称加入到该列表中,如果依赖的bean获取到为null,并且在创建中列表中,那么即使被依赖的bean未初始化完成,将会返回被依赖的对象。
真正创建对象的方法
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
//创建
try {
return createBean(beanName, mbd, args);
}
//创建
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
/**
* 实例化:对象创建的整个过程
* 初始化:对象new之后的过程,spring干预初始化的过程的重要接口是BeanPostProcesser,后置处理器的实现由非常多种。
*
* ClassA------XXXXBeanPostProcesser----ClassA()-----XXXBeanPostProcesser-@PostConstruct----
**/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。