Spring创建对象过程
- 层次结构
- AnnotationConfigApplicationContext
- GenericApplicationContext 继承
- AbstractApplicationContext 继承
- DefaultResourceLoader 继承
- ConfigurableApplicationContext 实现
- ApplicationContext继承
- EnvironmentCapable 继承
- ListableBeanFactory 继承
- BeanFactory 继承
- HierarchicalBeanFactory继承
- BeanFactory 继承
- MessageSource 继承
- ApplicationEventPublisher 继承
- ResourcePatternResolver 继承
- ResourceLoader 继承
- Lifecycle 继承
- Closeable 继承
- ApplicationContext继承
- DisposableBean 实现
- BeanDefinitionRegistry 实现
- AliasRegistry 继承
- AbstractApplicationContext 继承
- AnnotationConfigRegistry实现
- GenericApplicationContext 继承
具体类详解
BeanFactory
- 这个接口得意思就是说 获取bean信息 根据名称啊 类型啊 别名啊 是否单例的 bean工厂是否包含
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
ListableBeanFactory
- 这个类看起来其实意义不大
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
String[] getBeanDefinitionNames();
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(Class<?> type);
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
HierarchicalBeanFactory
- Hierarchical 层次的意思
- 只有设置父容器才会有
- 子容器可以访问父容器内容,父容器访问不了子容器内容
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
EnvironmentCapable
- Capable 能力的意思
- 环境变量属性啊什么的顶级接口
- Environment getEnvironment(); 意识就是可以获取环境的能力接口
- Environment也是一个接口 继承PropertyResolver 意思是说不光能获取系统信息 还可以解析property
- StandardEnvironment 看这个类就够了
MessageSource
- Strategy interface for resolving messages, with support for the parameterization and internationalization of such messages.
- 策略接口 国际化的 暂时先不看
ResourceLoader
- Strategy interface for loading resources
- 策略模式的核心个人理解是返回值是什么 Resource 那就太多了 xml 注解 file url inputStream 外部资源什么的
- 再看PropertyResolver 这个 是不是就能对应上了 这个解析属性 这边获取xml
- ResourceUtils 可以看下这个类 也可以根据前置判断资源类型
// classpath:
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
Resource getResource(String location);
ClassLoader getClassLoader();
ResourcePatternResolver
- classpath:只会加载第一个匹配的资源,而classpath*:会加载所有匹配的资源并合并成一个集合。
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String locationPattern) throws IOException;
ApplicationEventPublisher
- 事件发布 典型的监听器模式 可以发布给所有监听对象
- 这块设计就牛逼了 本来只有 ApplicationEvent 实现这个对象的才可以收到事件 第二个方法把Object 放在PayloadApplicationEvent里面 所以就变成了ApplicationEvent
void publishEvent(ApplicationEvent event);
void publishEvent(Object event);
Lifecycle
- 生命周期
- The typical use case for this is to control asynchronous processing. 异步调用执行
- This interface does not imply specific auto-startup semantics. Consider implementing {@link SmartLifecycle} for that purpose.
- 这都属于顶级接口了 意思就是所有的bean都是有生命周期的
void start();
void stop();
boolean isRunning();
Closeable
- public void close() throws IOException;
- 关闭看这个类就够了AbstractApplicationContext#doClose
- 发布关闭事件 getLifecycleProcessor().onClose(); destroyBeans(); closeBeanFactory(); onClose();
ConfigurableApplicationContext
- 这个接口就开始介入beanFactory ,后置处理器,刷新工作了
- refresh() 这个注释告诉我们 实例化所有或根本不实例化singletons
- getBeanFactory() Spring中大量get方法 get不到就doGet doGet不到就doCreate 典型的缓存模式
- SPI接口
- ApplicationListener 可以监听事件了
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
String ENVIRONMENT_BEAN_NAME = "environment";
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
void setId(String id);
void setParent(ApplicationContext parent);
void setEnvironment(ConfigurableEnvironment environment);
@Override
ConfigurableEnvironment getEnvironment();
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
void addApplicationListener(ApplicationListener<?> listener);
void addProtocolResolver(ProtocolResolver resolver);
void refresh() throws BeansException, IllegalStateException;
void registerShutdownHook();
@Override
void close();
boolean isActive();
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
- 理解一下registerShutdownHook()方法的操作(Connection conn相关信息删除效果也一样)
- 现象:The main thread ends execution. 这行打印完了 Database connection closed!继续打印出来了
- 这个是向jvm申请了一个钩子 在程序退出 异常什么情况导致的 调用了注册方法 这个就是释放资源时候最核心的东西了
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DataBaseConnectMain {
private static Connection conn;
public static void main(String[] args) {
System.out.println("The main thread starts executing");
// 初始化数据库连接
initConnection();
System.out.println("Do some data querying and processing");
// 注册关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
closeConnection();
}
});
System.out.println("The main thread ends execution.");
}
private static void initConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?useSSL=true&", "root", "root");
System.out.println("Database connection successful!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void closeConnection() {
try {
conn.close();
System.out.println("Database connection closed!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
DisposableBean
- void destroy() throws Exception;
- 这个还是挺常见的自定义实现组件 配合InitializingBean在bean初始化完了做一些工作 然后销毁的时候做一些工作 主要是针对连接资源什么的
类信息开始
AbstractApplicationContext
- 这个类目前看 需要实现上面所有接口的通用功能了
BeanDefinition注入过程
- ApplicationContext ac = new AnnotationConfigApplicationContext(Dog.class);
- 如果没有先创建一个RootBeanDefinition 构造器+属性 然后把beanClass设置进去
- 再看下DefaultListableBeanFactory#registerBeanDefinition
- this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName);
- 把bean信息放到beanDefinitionMap中
- AnnotatedBeanDefinitionReader#registerBean 看下这个方法 这个是根据注解把Dog信息放进去
- 先创建一个 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
- BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
- definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
- BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
- 结束
Spring内部初始化的后置处理器内容
- ApplicationContext ac = new AnnotationConfigApplicationContext(Dog.class);
- 构造器AnnotationConfigApplicationContext
- this.reader = new AnnotatedBeanDefinitionReader(this);
- this.scanner = new ClassPathBeanDefinitionScanner(this);
- 初始化4个BeanDefinitionHolder 初始化内部后置处理器 内部三个属性beanDefinition beanName aliases
- 下面是需要的内部后置处理器 如果具体想看累都干了哪些事情 看每个类的 postProcessBeanFactory , postProcessBeanDefinitionRegistry,postProcessBeforeInitialization
- ConfigurationClassPostProcessor -> org.springframework.context.annotation.internalConfigurationAnnotationProcessor
- postProcessBeanFactory 这个类主要是处理 @Configuration 这个类的
- 两大核心 enhanceConfigurationClasses(beanFactory); // 本次没走 是因为 没有注解
- beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
- AutowiredAnnotationBeanPostProcessor -> org.springframework.context.annotation.internalAutowiredAnnotationProcessor
- 继承抽象类InstantiationAwareBeanPostProcessorAdapter
- 这个类主要是处理 @Autowired 和 @Value 然后收集数据 Set lookupMethodsChecked , Map<Class<?>, Constructor<?>[]> candidateConstructorsCache,Map<String, InjectionMetadata> injectionMetadataCache
- RequiredAnnotationBeanPostProcessor-> org.springframework.context.annotation.internalRequiredAnnotationProcessor
+ - CommonAnnotationBeanPostProcessor -> org.springframework.context.annotation.internalCommonAnnotationProcessor
- 持久化的 不配置不注入进来 PersistenceAnnotationBeanPostProcessor -> org.springframework.context.annotation.internalPersistenceAnnotationProcessor
- EventListenerMethodProcessor -> org.springframework.context.event.internalEventListenerProcessor
- DefaultEventListenerFactory -> org.springframework.context.event.internalEventListenerFactory
- 构造器AnnotationConfigApplicationContext
未完待续