系列三:Spring框架介绍

源码地址:https://download.csdn.net/download/u013636987/11387400

上一篇:系列二:struts2参数传递

 Spring功能介绍

我们先不讨论Spring的好处,毕竟我个人觉得用久和用惯了,就会发现框架的方便还有代码的整洁。

那么Spring作用是什么,简单来说他就是一个工厂,你要生产什么产品,告诉他规格还有参数,他就帮你生产出产品。

我们都知道java是面向对象的编程,我们通常流程是先构造对象,然后实例化对象,然后使用new创建对象,然后就可以在某个方法里面使用这个对象了。而你只要告诉Spring创建对象的名称和值,这个工程就会自动帮你完成new创建对象,也就是说先构造对象,然后实例化对象,然后配置好xml给到工厂。然后你就可以某个类里面去set或者构造方法中获取这个被工厂生产出来的对象。

如下在配置文件中配置了property name="customerService" ,其中property表示set依赖注入

	<!-- 配置客户模块 -->
	<!-- 强调:以后配置Action,必须是多例的 -->
	<!-- 客户功能配置 -->
	<bean id="customerAction" class="com.customer.action.CustomerAction" scope="prototype">
		<property name="customerService" ref="customerService"/>
	</bean>
	<bean id="customerService" class="com.customer.service.CustomerServiceImpl">
		<property name="customerDao" ref="customerDao"/>
	</bean>

然后就可以在class=com.customer.action.CustomerAction的这个类中直接set

	// 提供service的成员属性,提供set方法
	private CustomerService customerService;

	public void setCustomerService(CustomerService customerService) {
		this.customerService = customerService;
	}

你会发现不用去new一个CustomerService对象。这一步Spring已经帮你做好了,你可以直接调用customerService的方法。

这个就是Spring中的控制反转技术(IoC) ,简单来说就是程序把创建对象的控制权反转给Spring工厂,由此进行对象的创建和依赖关系的维护。

 Spring启动流程和核心组件

Spring中的jar包,如下,其中有三个核心jar包,core,context,beans。core包侧重于帮助类,操作工具,beans包更侧重于bean实例的描述。context更侧重全局控制,功能衍生。

 

 简化的总体结构

core-》Context -》Bean

core的ResourceLoader加载资源,Resource接口屏蔽资源提供者提供资源

--------->Context 继承了 ResourceLoader 接口,获取资源--------->

ApplicationContext 是 Context 的顶级父类,他除了能标识一个应用环境的基本信息外,他还继承了五个接口,这五个接口主要是扩展了 Context 的功能。如下

1、AnnotationConfigApplicationContext:从一个或多个基于Java配置类中加载Spring应用上下文。 
2、AnnotationConfigWebApplicationContext:从一个或多个基于java的配置类中加载Spring Web应用上下文。 
3、ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,把应用上下文定义文件作为类资源。 
4、FileSystemXMLApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义。 
5、xmlWebApplicationContext:从Web应用的一个或多个xml配置文件中加载上下文定义。

 --------->ApplicationContext 继承了 BeanFactory 创建bean---------->

Bean 的创建时典型的工厂模式,他的顶级接口是 BeanFactory

 BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory。但终的默认实现类是 DefaultListableBeanFactory。实现多接口是为了区分在 Spring 内部操作对象传递和转化时,对对象的数据访问所做的限制。例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,HierarchicalBeanFactory 表示的是这些 Bean 是有继承关系的,也就是每个 Bean 有可能有父 Bean。AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为

Spring启动流程

首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;

contextLoaderListener监听事件

其次,在web.xml中会提供有contextLoaderListener。在web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,这是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的context-param标签指定。在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取; 

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

此部完成后spring已经通过classpath:applicationContext.xml读到了配置文件,完成对bean的解析和配置,如果有组件工厂,生成相对应的Factory,如下生成session的持久化工厂。

	<!-- LocalSessionFactoryBean加载配置文件 -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<!-- 先加载连接池 -->
		<property name="dataSource" ref="dataSource"/>
		<!-- 加载方言,加载可选 -->
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		
		<!-- 引入映射的配置文件 -->
		<property name="mappingResources">
			<list>
				<value>com/customer/model/Customer.hbm.xml</value>
				<value>com/login/model/Login.hbm.xml</value>
				<value>com/logger/model/Logger.hbm.xml</value>
				<value>com/authorization/model/Authorization.hbm.xml</value>
			</list>
		</property>
	</bean>

 

启动servlet或者封装了servlet的struts2或spring mvc

contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个servlet可以配置多个,

例如spring mvc为DispatcherServlet,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文。在建立DispatcherServlet自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先从ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的parent上下文。有了这个parent上下文之后,再初始化自己持有的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。这个servlet自己持有的上下文默认实现类也是xmlWebApplicationContext。初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为Key,而是通过一些转换,具体可自行查看源码)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(上面初始化的上下文)定义的那些bean。

但是此项目并没有用到spring mvc,本项目是配置好struts2,然后把本来应该struts2自己创建的action反转给spring创建。

spring配置文件中配置

	<bean id="customerAction" class="com.customer.action.CustomerAction" scope="prototype">
		<property name="customerService" ref="customerService"/>
	</bean>

struts2配置文件中配置 

	<action name="customer_*" class="customerAction" method="{1}">

因为struts2已经配置好了,拦截器已经启动,当jsp页面向服务器发出请求,被ActionServlet拦截。ActionServlet根据用户的请求在struts配置文件中查找与之对应的Action(Spring创建的),同时将用户的数据填充给对应的ActionForm,然后将ActionForm一起分发给Action进行处理,Action会自动调用相应的方法,将从ActionForm里面获取用户填写的数据。

综上所述:

spring作为核心业务层,通过bean创建控制层的action,本身的service,还有持久层的session。然后通过依赖注入。session注入service,service注入action。达到对象的创建和依赖关系的维护目的。从而实现MVC: Model + View + Controller(数据模型+视图+控制器)

<!--sessionFactory注入customerDao,customerDao注入customerService,customerService注入customerAction-->

	<bean id="customerDao" class="com.customer.dao.CustomerDaoImpl">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	<bean id="customerService" class="com.customer.service.CustomerServiceImpl">
		<property name="customerDao" ref="customerDao"/>
	</bean>
	<bean id="customerAction" class="com.customer.action.CustomerAction" scope="prototype">
		<property name="customerService" ref="customerService"/>
	</bean>
发布了39 篇原创文章 · 获赞 2 · 访问量 5033

猜你喜欢

转载自blog.csdn.net/u013636987/article/details/96569803