Fork me on GitHub

spring复习

Spring Ioc 依赖查找&注入

Spring Ioc 依赖查找&注入

根据bean 名称进行查找
  • 实时查找 beanFactory.getBean(Striing);
  • 延时查找 ObjectFactory
根据bean类型进行查找
  • 单个bean对象 beanFactory.getBean(Person.class);
  • 集合bean对象
根据bean名称+类型查找
根据java注解查找
  • 单个bean对象
  • 集合bean对象
根据bean名称注入
根据bean类型注入
  • 单个bean对象
  • 集合bean对象
注入容器内建Bean对象
例如 Environment
bean名称 bean实例 使用场景
Environment Environment对象 外部化配置和profiles
systemProperties java.util.properties对象 java系统属性
systemEnvironment java.util.Map 对象 操作系统环境变量
messageSource MessageSource对象 国际化文案
lifecycleProcessor lifecycleProcessor对象 lifecycle bean 处理器
applicationEventMulticast applicationEventMulticast spriing事件管理器
注入非Bean对象 beanFactory

注入类型

  • 实时注入
  • 延迟注入

BeanFactory 和ApplicationContext 谁才是真正的ioc 容器?

ApplicationContext 除了ioc 容器角色,还有

  • 面向切面aop
  • 配置元信息 configuration metadata
  • 资源管理 resources
  • 事件 events
  • 国际化i18n
  • 注解 annotations
  • environment 抽象(environment abstraction)
Spring bean

BeanDefinition 元信息

属性 (Property) 说明
Class bean全类名
Name bean的名称或者Id
Scope bean的作用域 (singleton,prototype)
constructor arguments bean构造器参数(用于依赖注入)
properties bean 属性设置(用于依赖注入)
autowring mode 自动绑定模式(byName、byType)
Lazy initialization mode 延迟初始化模块(延迟、非延迟)
initialization method bean初始化回调方法
Destruction method bean 销毁回调方法
BeanDefinition 构建
  • 通过BeandefiniationBulider 构建
  • 通过AbstractBeanDefinition 以及派生类

实例化springbean

  • 通过serverLoaderFactoryBean
  • 通过AutowireCapableBeanFactory#createBean(java.lang.class,int boolean)
  • 通过BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)

初始化SpringBean

  • @PostConstruct 标注方法
  • 实现InitializingBean 接口的afterPropertiesSet()方法
  • 自定义初始化方法
    • xml配置
    • Java 注解 @Bean(init-method=”init”)
    • Java Api AbstractBeanDefinition#setInitMethodName(String);

[^这三种实现顺序为: postContruct —>iinitializing—>自定义方法]:


大家都知道创建一个javaweb项目都需要从web.xml开始配置,那么项目中要使用spring,spring
容器是怎么启动的呢,需要在web.xml中进行配置,

eaglemvc
org.springframework.web.servlet.DispatcherServlet

contextConfigLocation
classpath:spring/eagle-servlet.xml

1

也就是DispatcherServlet 看起,从名字上就能看出来他也是一个servlet,那么他必须有init
(),doGet(),doPost(),destory()方法。我们肯定从init方法开始,发现没有init方法呢?
这个时候看这个DispatcherServlet 类,ctrl+H 查看下类继承的关系,发现他有父类,
frameworkServlet,HttpServletBean,HttpServlet .

发现 HttpServletBean 中有init方法,其中代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

@Override
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
}

// Set bean properties from init parameters.
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
throw ex;
}

// Let subclasses do whatever initialization they like.
initServletBean(); //注意这里人家写注释了,发现调用初始化Bean的对象了,但是方法是空的,那就是让子类去实现了呗。

if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}

本文欢迎转载,但是希望注明出处并给出原文链接。 如果你有任何疑问,欢迎在下方评论区留言,我会尽快答复。 如果你喜欢或者不喜欢这篇文章,欢迎你发邮件到 alonecong@126.com 告诉我你的想法,你的建议对我非常重要。

------ 本文结束感谢您的阅读! ------
0%