一、IOC概述
Inversion of control 控制反转。
一般情况下,一个Java对象使用依赖类时,往往需要自己创建一个依赖类的对象。创建一个依赖类的对象时,可能需要检查类是否存在,类是否能安全访问等;创建依赖类的对象后,还需要管理对象的生命周期。这些操作都增加了类之间的耦合度。
IOC的核心思想就是让一个代理人(Spring容器)来统一管理对象之间的依赖关系以及对象的生命周期,代理人会主动创建对象(指明依赖注入时,文件配置注入或者注解注入)或者需要时主动找代理人要;这样Java对象的依赖关系和生命周期管理就由自己控制变为代理人控制,所以称为控制反转。
Spring实现了代理人的功能!实现具体细节有一下几点:
DI:dependency injection 依赖注入
注解注入在xml文件注入之前完成,所以xml注入会覆盖注解注入;
注解注入的使用
//@Required
//@Autowired
//@Resource等
"/>
//暂时不清楚怎么用
在Spring applicationContext.xml中定义以上bean等价于:
only looks for annotations on beans in the same
application context in which it is defined. This means that, if you put
in a WebApplicationContext for a DispatcherServlet, it
only checks for @Autowired beans in your controllers, and not your services.
指定扫描包的路径的配置是:
分隔符可以是:逗号,分号,空格,tab符,换行符;
以上配置默认包括
扫描过滤器:
public enum FilterType {
ANNOTATION,
ASSIGNABLE_TYPE,
ASPECTJ,
REGEX,
CUSTOM
}
xml文件注入
配置包含bean定义的xml文件,指定给Spring容器
Spring Bean定义
class
|
bean的类
|
name
id
|
定义bean的命名
定义bean的id
|
scope
|
bean的生命周期类型
|
constructor arguments
|
指定构造器参数
|
properties
|
指定属性的依赖bean,实现注入
|
lazy-initialization mode
lazy-init
|
true-不会预初始化,只有调用时才会被初始化
false-bean注入时初始化
默认true
|
Spring Bean工厂
DefaultListableBeanFactory
Spring bean 容器
FileSystemXmlApplicationContext
ClassPathXmlApplicationContext
GroovyWebApplicationContext
XmlWebApplicationContext
AnnotationConfigWebApplicationContext
bean资源定位器
ClassPathResource //抽象类路径的资源
FileSystemResource //抽象文件系统类的资源
bean定义接口关系
BeanDefinition<-AbstractBeanDefinition<-RootBeanDefinition
<-GenericBeanDefinition
<-ChildBeanDefinition
<-AnnotatedBeanDefinition
二、
Spring bean容器初始化的触发
初始化方法一,在应用部署文件中指定Spring监听容器启动的监听器,
org.springframework.web.context.ContextLoaderListener
如果没有使用监听器启动Spring的bean容器,还可以使用web.xml的servlet的启动来完成,
rest
org.springframework.web.servlet.DispatcherServlet
1
如果要指定DispatcherServlet的配置文件,参数名一定是字符串"
contextConfigLocation"
<
init-param
>
<
param-name
>
contextConfigLocation
param-name
>
<
param-value
>
classpath:spring-mvc.xml
param-value
>
init-param
>
web.xml中的servlet组件配置的Servlet必须继承javax.servlet.Servlet,Servlet容器在部署应用的时候会初始化指定的Servlet类。
DispatcherServlet类的实现如下:
DispatcherServlet extends FrameworkServlet...
FrameworkServlet extends HttpServletBean...
HttpServletBean extends HttpServlet...
javax.servlet.http.HttpServlet是javax.servlet.Servlet接口的实现类。
Servlet初始化的时候,HttpServletBean的init()会被执行,init()方法调用了FrameworkServlet的initServletBean()方法,该方法实现了Spring bean容器的初始化。
web.xml中组件的加载顺序:context-param -> listener -> filter -> servlet
也可以自己实现ServletContext容器启动监听器,在监听器中完成系统需要的启动插件。
Spring获取bean的方法
在B/S场景下,因为有Servlet容器,所以应该尽可能依靠Servlet容器构建bean容器。如下,
方法一
/**
* 第一种:使用ContextLoader,顶层容器加载类
* 需要依靠Servlet容器
*/
public static ApplicationContext getContext(){
return ContextLoader.getCurrentWebApplicationContext();
}
/**
* 第二种:使用WebApplicationContextUtils,从Servlet容器中获取顶层容器
* getWebApplicationContext(ServletContext sc)默认获取顶层容器
* 需要依靠Servlet容器
* @return
*/
public static ApplicationContext getContext(ServletContext context){
return WebApplicationContextUtils.getWebApplicationContext(context);
}
/**
* 第3种:自己选择容器类,这种不需要依靠Servlet容器
*/
public static ApplicationContext getContext(String[] config){
return new ClassPathXmlApplicationContext(config);
//或者
//return new FileSystemXmlApplicationContext(config);
}