我不是语言的开发者,我只是它的搬运工。
1. InitializingBean接口
它只有一个方法
void afterPropertiesSet() throwsException;
官方解释是:Invoked by aBeanFactory after it has set all bean properties。翻译过来是bean的所以属性都设置完毕后BeanFactory会调用该方法。如果在bean里指定了init-method初始化方法,BeanFactory会先调用afterPropertiesSet然后再调用init-method指定的方法,建议不继承InitializingBean接口,避免与spring的耦合。
2. DisposableBean接口
它只有一个方法
void destroy() throws Exception;
官方解释:Invoked by aBeanFactory on destruction of a singleton。
翻译过来:在单例bean被销毁之前调用destroy()方法。如果在bean里指定了destroy-method销毁方法,BeanFactory会先调用destroy然后再调用destroy-method指定的方法。注意destroy指的是单例,因为当指定指定的生命周期是prototype时,bean由客户端自己管理,容器不在管理bean。
3. ServletContextAware接口继承Aware
只有一个方法:
setServletContext(ServletContextservletContext)
官方解释:Set the {@link ServletContext} that this object runs in Invokedafter population of normal bean properties but before an init callback likeInitializingBean's {@code afterPropertiesSet} or a custom init-method.
翻译过来:方法在普通的bean的属性设置完后但在调用afterPropertiesSet或指定的init-method方法之前调用。
目的:为了拿到ServletContext对象。
一个web应用只有一个ServletContext,任何地方访问都是同一个ServletContext, servletContext 定义了一个Servlet的环境对象,通过这个对象,Servlet引擎向Servlet提供环境信息
4. EnvironmentAware接口继承Aware
只有一个方法:
setEnvironment(Environment environment);
目的:为了拿到Environment对象 需要慎重研究
5. BeanNameAware接口继承Aware
只有一个方法:setBeanName(Stringname)
官方解释:Set the nameof the bean in the bean factory that created this bean
翻译过来:在BeanFactory容器创建bean时设置bean的name。
目的:获得beanName。
Spring在设置Bean配置之后,且在调用任何Bean生命周期回调(初始化或者销毁)方法之前就自动调用这个方法。这样可以知道beanName。但与spring的耦合度很高。
6. BeanFactoryAware接口继承Aware
只有一个方法:setBeanFactory(BeanFactorybeanFactory) throws BeansException
官方解释:Callback thatsupplies the owning factory to a bean instance
翻译过来:获得BeanFactory一个实例。
目的:获得BeanFactory容器的引用。
Spring会自动调用方法传入beanFactory
7. BeanPostProcessor接口
2个方法:
postProcessBeforeInitialization(Objectbean, String beanName)
官方解释:Apply thisBeanPostProcessor to the given new bean instance <i>before</i> anybean initialization callbacks (like InitializingBean's {@codeafterPropertiesSet} or a custom init-method)
翻译过来:在new 该实例时会在afterPropertiesSet或init-method指定的方法之前调用该方法。
postProcessAfterInitialization(Objectbean, String beanName)
在new 该实例时会在afterPropertiesSet或init-method指定的方法之后调用该方法。
目的:希望在Spring IoC容器初始化受管Bean之前、属性设置之后对该Bean先做一些预处理,或者在容器销毁受管Bean之前自己释放资源。
如果这个接口的某个实现类被注册到某个容器,那么该容器的每个受管Bean在调用初始化方法之前,都会获得该接口实现类的一个回调。容器调用接口定义的方法时会将该受管Bean的实例和名字通过参数传入方法,经过处理后通过方法的返回值返回给容器。根据这个原理,我们就可以很轻松的自定义受管Bean。只要将这个BeanPostProcessor接口的实现定义到容器中就可以了。它是对整个容器里bean而言的,范围更大,不要和init-method()方法做比较。
8. FactoryBean接口
3个方法:
T getObject():返回被该FactoryBean代理的实例。
Class<?> getObjectType():返回被该FactoryBean代理的实例类型。
boolean isSingleton():确认返回的实例是不是单例。
目的:代理真实的Bean。getObject会返回真实的bean。
以Bean结尾,表示它是一个Bean。 Spring容器getBean(id)时见到bean的定义是普通class时,就会构造该class的实例来获得bean,而如果发现是FacotryBean接口的实例时,就通过调用它的getObject()函数来获得bean。如果要获取FactoryBean对象,可以在id前面加一个&符号来获取。作用其实是类的代理。
9. DelegatingFilterProxy类
该类是个过滤器,但又不是过滤器,其实是过滤器的代理,且只能代理Filter,这个类位于spring-web-XXX.jar这个jar下面,DelegatingFilterProxy类继承于抽象类GenericFilterBean,间接地implement 了javax.servlet.Filter接口。一般我们将其它框架实现的过滤器添加到该类里。看看它有什么属性。
一般我们只设置targetBeanName和targetFilterLifecycle。
targetBeanName:一般通过设置 targetBeanName来指定被代理的Filter名字,如果没有指定则使用 DelegatingFilterProxy的beanName作为被代理的Filter的名字。
targetFilterLifecycle:是否调用Filter的init和destroy方法,默认为false。
ps: contextAttribute,使用委派Bean的范围,其值必须从org.springframework.context.ApplicationContext.WebApplicationContext中取得,默认值是session
设置了DelegatingFilterProxy则指定的Filter即可调用了。比如在SpringMVC里,执行顺序是listener->filter->servlet。那么我们指定的filter会在DispatcherServlet得到请求之前执行即可拦截所以有请求。通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的。接收到一切请求都会将request和response传到被代理的过滤器里。
10. ContextLoaderListener类
目的:初始化WebXmlApplicationContext并初始化容器上下的配置信息。实例化IoC容器,并将此容器实例注册到ServletContext中。
也可以说它是web的启动入口。因为它实现了ServletContextListener这个接口而该接口的2个方法:
void contextInitialized ( ServletContextEvent sce ),
官方解释:Notification that the web applicationinitializationprocess is starting.
All ServletContextListeners are notified ofcontextinitialization before any filter or servlet in the web application isinitialized
翻译过来:在web应用启动时该接口的实现类会被通知,在任何过滤器或servlet初始化之前所以实现该接口的子类都会被通知。
可以说该类是由web服务器调用,并将ServletContext向下传递。这样我们拿到了ServletContext即拿到了应用的上下文配置信息。ServletContext 被 Servlet 程序用来与 Web 容器通信,每个应用只有一个ServletContext, 被Web 应用内的各个程序共享, Context 可以用来保存资源并且共享,所以我所知道的ServletContext 的最大应用是Web 缓存。
contextDestroyed ( ServletContextEvent sce )
在所以过滤器和servlet销毁后才会被调用。ContextLoaderListener主要功能都在ContextLoader里实现。
我们常在web.xml里这样配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/*.xml</param-value>
</context-param>
contextConfigLocation是什么意思呢?其实它是ContextLoader时一个常量,ContextLoader负责读取资源并注册到configureAndRefreshWebApplicationContext里。而configureAndRefreshWebApplicationContext用于配置XmlWebApplicationContext,读取web.xml中通过contextConfigLocation标签指定的XML文件,实例化XML文件中配置的bean,并在上一步中实例化的容器中进行注册。
ContextLoaderListener实现了ServletContextListener接口,所以应用启动时,该类会得到服务器的自动调用,也就拿到了ServletContext。而又继承了ContextLoader类,而ContextLoader负责实例化spring容器并解析contextConfigLocation指定的配置文件,加载配置过程由ContextLoader 来完成,所以我们不会在web.xml里定义bean。
Spring需要的学习的类太多,一篇文章写不完,以后再慢慢总结。敬请期待。