大致内容

    spring基本概念

    IOC入门

【17.6.9更新】,如何学习spring?

  掌握用法

  深入理解

  不断实践

  反复总结

  再次深入理解与实践

一、Spring相关概念

   1.概述:    

    Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的容器(container)

      无论从大小和开销还是来说,都足以称得上是轻量级的框架
    由Rod Johnson创建。
    简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架

    可以说,spring带来了复杂JavaEE开发的春天!

  【更新】spring是一个解决方案级别的整合框架,主要是用来作解耦

  2.核心有两部分:

    IOC:控制反转
      对象创建不是通过new,而是通过配置交给Spring管理
    AOP:面向切面编程
      所以AOP的本质是在一系列纵向的控制流程中,把那些相同的子流程提取成一个横向的面

    是一种容器,它会管理由他创建的对象,包括生命周期的管理等。

  3.一站式框架
    在JavaEE三层架构中,每一层都提供了不同的解决方案
    web层:SpringMVC
    service层:IOC
    dao层:jdbcTemplate

    对应JavaWeb阶段的三层架构:

    

  

  4.使用的版本
    Spring4.x的版本

  5.Spring包的下载方式
    http://www.open-open.com/news/view/1eb1613

    将文章大致内容提取出来就是:

       找到 spring framework

     找到All avaible features and modules are described in  the Modules section of the reference documentation .

        Their  maven/gradle coordinates are also described there

     这个就是各个spring版本的下载地址:  http://repo.spring.io/release/org/springframework/spring 而且很清楚的告诉你下载哪个文件。
     (等待maven依赖管理的更新)

 二、IOC(Inverse of Control)控制反转

  【更新】:面向接口编程 每一层只向外提供接口,各层之间只依赖接口而不依赖具体的实现,用于隐藏具体实现并实现多态的组件

    什么被反转了?获得依赖对象的过程被反转了

  IOC主要的观点就是借助第三方(也就是IOC容器)实现依赖关系的对象之间的解耦

  更多详细的IOC与DI的阐述,请参见http://www.cnblogs.com/xdp-gacl/p/3707631.html

  1.对象创建交给Spring管理

    【更新】:应用程序本身并不负责依赖对象的创建和维护,由IOC容器负责创建和维护

      (IOC容器初始化的时候会创建一系列的bean,并存在spring的上下文中,ApplicationContext)

  

   2.Ioc管理分为两部分:

  【更新,初始化IOC容器的方法(WEB应用中) listen可以通过context-param】 主要是指定 contextConfigLocation

    1)Ioc配置文件
    2)Ioc注解 

  (1)==Ioc的底层原理:
      主要用到的技术
        xml配置文件
        dom4j解析配置文件
        工厂设计模式
        反射

之前代码:
一个User类:
public class User{
public void add(){
...
}
}  

  想调用add方法,需要构建类的对象,再调用:
    User user = new User();user.add();
  如果想在servlet中使用,需要将上述代码写在servlet中,但如果原来的类名、方法名发生了修改
  则servlet也要同步修改,耦合度太高,不方便!

    针对这种情况,提出第一阶段的解决方案:
      工厂模式,使用此模式进行解耦操作

public class UserService{
public void add(){
...
}
}
做法是建立一个工厂类:
public class UserFactory{
//提供静态方法返回
public static UserService getService(){
return new UserService();
}
}
在servlet中调用可以使用工厂:
UserFactory.getService().add();
这样就相对降低了和类的耦合度
但缺陷是和工厂类又有耦合度(高内聚,低耦合)

     IOC的解决的大概过程:
      要在servlet得到UserService类的实例
    步骤:
      第一步:创建xml配置文件,配置需要创建的对象的类;
          <bean id="userService" class="cn.UserService">
      第二步:创建工厂类,使用dom4j解析配置文件+反射
          解析xml得到指定id值得class属性值:类路径
          采用反射创建类的对象
          得到类对象过程还是通过工厂:Factory.getUserService();
          此时类名称发生变化时,只需要变更xml配置文件即可

  (2)IOC入门案例:
    第一步:
      导包:jar包里每个都有三个jar包,分别是jar包、doc、源码
          spring核心组件有四个(如图)

分别是:beans core context spEL(表达式的,导expression的包)
再导入支持日志输出的jar包(spring本身并不提供日志jar包)【log4j的使用在后面作补充】
  log4j logging 两个jar包

  也就是如图六个jar包

  第二步:
    创建类和方法
    例如创建User类和add()方法

package cn.ioc;

public class User {

    public void add(){
System.out.println("spring_ioc_add");
}
}

  第三步:
    创建spring配置文件,配置创建的类
    前面两个框架的名称和位置固定,而spring不是,但一般都建议放在src下,【更新】:一般放在与src同级的 source folder 下。
    建议名字为 applicationContext.xml
    自定义命名请参考:http://huihai.iteye.com/blog/1019281
    但完全可以自定义名字(位置建议src!)

      在web.xml中指定spring路径:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/beans.xml</param-value>
</context-param>

    比如这里创建一个 bean1.xml
    创建完xml文件,首先是引入约束(这里是schema约束!)
    进入包里的docs->spring framework reference->html->找最后一个文件 (见图!)

    【更新】:现在由 springIDE来做这件事

    引入schema约束:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!--ioc入门-->
<bean id="user" class="cn.ioc.User"></bean>
</beans>

  注意:id建议与类同名,首字母改为小写(这也是spring的默认命名策略)

  第四步:
    简单测试
      步骤:
        加载核心配置文件
        得到对象
        具体不再赘述,见testIoC

package cn.ioc;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestIoC { //只是测试这样写,实际开发并不这样操作
@Test
public void test(){
//加载spring核心配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
//得到配置创建的对象
User user =(User)context.getBean("user");
user.add();
}
}

  //配置文件没有提示的问题(无法上网,类比之前dtd引入,但稍有区别)此处不再赘述,全部在另外一篇同分类引入约束的博客介绍

  (3)spring的bean管理基于配置文件,day02注解方式
    ==bean实例化的三种方式:(常用一种方式)
      1)使用类的无参构造器(常用)
        上面的入门案例
        <bean id="user01" class="cn.ioc.User"></bean>
        会自动找无参的构造器
      2)使用静态工厂创建
        在类里使用静态方法返回实例对象
        <bean id="user02" class="cn.factory.BeanFactory" factory-method="getBean"></bean>
        依旧使用context.getBean()方法得到bean
      3)使用实例工厂创建
        创建一个不是静态的方法返回类的对象,使用此方式先要创建工厂的对象
        <bean id="bean3Factory" class="cn.factory.Bean3Factory"></bean>
        <bean id="user03" factory-bean="bean3Factory" factory-method="getBean"></bean>
      2、3仅作了解,实际开发用的一般是方式1   

  ==bean标签常用属性的介绍:
    id : 表示起的名称(一般不要包含特殊符号) ,可以根据id值得到配置的对象
    class : 要创建对象所在类的全路径
    name : (一般已经不用了) 功能和id类似,也可以得到bean对象(id值不能得到特殊符号),
        属于遗留问题,为了整合原来的struts1的
    scope : bean的作用范围:一般掌握两个值:
        singleton:单例 (默认)
        prototype:多例(应用于struts2的多实例的action)
      可以分别拿到两个对象比较对象地址

  (4)属性注入:创建对象的时候,也可以向类的属性设置值
    属性注入的方式:支持级联属性的注入(但是必须初始化(不会像struts2一样自动创建,当然,很多时候我们都用不着))
      原始方式:
      有参构造注入
      set()方法注入【用的最多】
      接口注入(用的少)

  spring只支持前两种方式的注入:
    spring有参构造注入:
    建立类

package cn.propertiry;

import java.util.List;
import java.util.Map;
import java.util.Properties; public class PropertiryDemo01 { private String username; public PropertiryDemo01(String username) {
this.username = username;
}
public void print(){
System.out.println("有参构造属性构造:"+username);
} }

  配置文件修改:

 <!-- 使用有参构造器属性注入 -->
  <bean id="prop01" class="cn.propertiry.PropertiryDemo01">
    <constructor-arg name="username" value="jiangbei"></constructor-arg>
  </bean>

  (不出现name属性时,把约束后面的spring-beans-4.0补上)

<!-- 有参构造注入 -->
<bean id="id" class="class">
<!-- name必须和构造器的参数名一致,ref为需要注入的引用 -->
<constructor-arg name="" ref=""/>
</bean>

  spring的set方式注入【最常用】:
    依旧是:创建类 配置文件配置 简单测试

package cn.propertiry;

public class Book {

    private String BookName;//属性
//set()方法
public void setBookName(String bookName) {
BookName = bookName;
} public void print(){
System.out.println("set属性注入:"+BookName);
}
}

  修改配置文件

<!-- set()方法属性注入 -->
<bean id="book" class="cn.propertiry.Book">
  <property name="BookName" value="从入门到放弃"></property>
</bean>

【实用】真正开发中不止是注入字符串,更多的是对象的注入等!
  例如service中依赖dao,需要dao的属性,可以进行属性注入(只是注入的是对象!)
  将new的过程交给spring实现!
  先建立两个类 Service Dao

package cn.propertiry;

public class Service {

    //定义dao成员变量
private Dao dao;
public void setDao(Dao dao) {
this.dao = dao;
} public void add(){
//service中要调用dao的add()方法需要得到其对象
dao.add();
}
}

  

package cn.propertiry;

public class Dao {

    public void add(){
System.out.println("dao.add");
}
}

  在Service中依赖dao对象,定义变量,生成set()方法
  进行配置(ref):

 <!-- 属性注入,注入对象 -->
<bean id="dao" class="cn.propertiry.Dao"></bean>
<!-- 注入dao对象 -->
<bean id="service" class="cn.propertiry.Service">
  <!-- name为成员变量名,ref为dao的bean的id -->
  <property name="dao" ref="dao"></property>
</bean>

  当然是可以通过多行注入多个属性的。

  名称空间注入:(也可以实现属性注入)只引出概念,不作演示赘述(用的太少)

  ===spring注入复杂数据(会用)
    例如注入list 注入数组 注入map 注入propertites
    都在案例:Prop类里
    定义成员
    生成set

package cn.propertiry;

import java.util.List;
import java.util.Map;
import java.util.Properties; public class Prop { //注入复杂数据类型
private String[] strs;
private List<String> list;
private Map<String,String> map;
private Properties props; public void setStrs(String[] strs) {
this.strs = strs;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProps(Properties props) {
this.props = props;
} public void print2(){
System.out.println("array:"+strs);
System.out.println("list:"+list);
System.out.println("map:"+map);
System.out.println("props:"+props);
}
}

    配置注入(所有的注入都必须先有对象(相关数据)生成)

      如果是配置引用,可以使用 value-ref等(按alt /即可见名知意)

      也可以配置独立的bean(导入util的命名空间),以供多出引用

<!-- 注入复杂属性 -->
<bean id="p" class="cn.propertiry.Prop">
<!-- 进行属性注入 -->
<!-- 数组 -->
<property name="strs">
<list>
<value>sx</value>
<value>sy</value>
<value>sz</value>
</list>
</property>
<!-- list -->
<property name="list">
<list>
<value>lx</value>
<value>ly</value>
<value>lz</value>
</list>
</property>
<!-- map -->
<property name="map">
<map>
<entry key="mx" value="mvx"></entry>
<entry key="my" value="mvy"></entry>
<entry key="mz" value="mvz"></entry>
</map>
</property>
<!-- props -->
<property name="props">
<props>
<!-- props的value值写在标签里 -->
<prop key="px">pvx</prop>
<prop key="py">pvy</prop>
<prop key="pz">pvz</prop>
</props>
</property>
</bean>

  最后,贴出整个演示的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- bean definitions here ioc入门-->
<bean id="user" class="cn.ioc.User"></bean> <!-- 使用有参构造器属性注入 -->
<bean id="prop01" class="cn.propertiry.PropertiryDemo01">
<constructor-arg name="username" value="jiangbei"></constructor-arg>
</bean> <!-- set()方法属性注入 -->
<bean id="book" class="cn.propertiry.Book">
<property name="BookName" value="从入门到放弃"></property>
</bean>
<!-- 属性注入,注入对象 -->
<bean id="dao" class="cn.propertiry.Dao"></bean>
<!-- 注入dao对象 -->
<bean id="service" class="cn.propertiry.Service">
<!-- name为成员变量名,ref为dao的bean的id -->
<property name="dao" ref="dao"></property>
</bean> <!-- 注入复杂属性 -->
<bean id="p" class="cn.propertiry.Prop">
<!-- 进行属性注入 -->
<!-- 数组 -->
<property name="strs">
<list>
<value>sx</value>
<value>sy</value>
<value>sz</value>
</list>
</property>
<!-- list -->
<property name="list">
<list>
<value>lx</value>
<value>ly</value>
<value>lz</value>
</list>
</property>
<!-- map -->
<property name="map">
<map>
<entry key="mx" value="mvx"></entry>
<entry key="my" value="mvy"></entry>
<entry key="mz" value="mvz"></entry>
</map>
</property>
<!-- props -->
<property name="props">
<props>
<!-- props的value值写在标签里 -->
<prop key="px">pvx</prop>
<prop key="py">pvy</prop>
<prop key="pz">pvz</prop>
</props>
</property>
</bean>
</beans>

  【更新】:使用外部属性配置文件(场景就是读取数据源等信息)

    之前可以使用此种形式:缺点很明显,如果需要修改数据库的配置信息,将比较复杂,需要拿出spring的配置文件

<!-- 数据库连接池 (此时使用的是dbcp,效率不高,仅作演示使用)-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
</bean>

    我们将这些属性抽取到db.properties:(一般而言,我们都是给Key这里起类似 jdbc.username这样的以.分割的形式,因为有时候直接写username非常容易和其他的(如系统的用户名)相冲突)

jdbc.user=root
jdbc.password=1230
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///test jdbc.initPoolSize=5
jdbc.maxPoolSize=10

    我们加入context的命名空间(使用springIDE,更简单,更强大!),在配置文件中进行属性文件位置的配置:

<!-- 导入属性文件 -->
<context:property-placeholder location="classpath:db.properties"/>

    如何在配置文件中取值我们之前已经提过,使用类似EL的形式:${val}

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="5"/>
</bean>

  //当然,这些配置都可以通过编码方式来代替,实现真正的全注解无配置开发

  【更新】 spring的SpEL:为配置文件动态赋值提供了可能

    使用#{...},可以动态引用其它对象,动态引用其它对象的属性值(字面值这里不做阐述)

     value="#{car.price}",注解形式:

           @Value("#{testConstant.STR}")

          private String str;

      并且还支持一些基本的运算,以及三目判断运算符等其他的待补充

  【更新】 spring容器的生命周期方法:init-method 和 destroy-method

  重要概念:
    IoC和DI的区别:
  IoC:控制反转,将对象的创建交给spring管理
  DI:依赖注入,向类的属性中设置值
  DI需要在IoC的基础上进行操作(需要在对象创建的基础上进行)

  【更新】:DI是IOC的一种更简单的诠释,也就是说:通过引入IOC容器,利用依赖注入的方式,实现对象之间的解耦

  【更新】bean的作用域(与struts2整合时使用到)

      prototype(每次请求都创建新的实例,使用hashCode判断) singleton request session

      bean的生命周期

      定义

      初始化

        (比较简便的配置是bean中配置init-method destroy-method的配置)

        当然不使用配置的时候可以通过bean实现 initlizaingBean disposiableBean两个接口,覆盖方法

          当然,也可以配置全局的初始化和销毁方法(就近原则 全局的最后执行)

      使用

      销毁

第一天的最后引出整合的一些基本概述(后面day会做补充)

===spring整合web项目
  Hibernate时有一个遗留问题:sessionFactory的创建会比较慢,可以交给服务器来创建
  还有上面的bean1.xml每次都要加载spring核心配置文件,会影响性能
  以上的类似问题,解决的实现思想都是:
    把加载配置文件和创建对象在服务器启动时就创建,把压力给服务器
  spring中封装了相关的处理类,这里简单介绍原理:

  web阶段中有一个与天地同寿的对象 ServletContext
  它的创建可以由监听器进行监听
  在服务器启动的时候,服务器会为每个项目创建一个独一无二的对象:ServletContext
  可以使用监听器对ServletContext进行监听,可以知道对象的创建时间
  于是可以在监听器监听到ServletContext创建后
  加载spring配置文件,把配置文件中配置的对象进行创建
  对象创建后将创建的对象放在ServletContext中(它也是一个域对象)
  域对象的存取数据直接使用get/setAttribute()即可

Spring第一天——入门与IOC的更多相关文章

  1. Spring入门导读——IoC和AOP

    和MyBatis系列不同的是,在正式开始Spring入门时,我们先来了解两个关于Spring核心的概念,IoC(Inverse of Control)控制反转和AOP()面向切面编程. 1.IoC(I ...

  2. Spring入门2. IoC中装配Bean

    Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...

  3. Spring入门1. IoC入门实例

    Spring入门1. IoC入门实例 Reference:Java EE轻量级解决方案——S2SH 前言: 之前学习过关于Spring的一点知识,曾经因为配置出现问题,而总是被迫放弃学习这些框架技术, ...

  4. Spring第一课:IOC控制反转,什么是反转,什么又是控制?

    前言 学习Spring第一课,就是认识IOC控制反转,要了解它还真得花一些功夫.今天主要理解透彻它的真谛,而不仅限于表面. 上道小菜 public class BusinessService { pr ...

  5. Spring_第一个Spring入门案例IOC

    今天我们来写我们的第一个spring 第一步 建立一个java project 第二步 添加我们的五个jar文件 第三步 在项目中建立一个com.zk.spring包 第四步 建立我们的userser ...

  6. spring jpetstore研究入门(zz)

    spring jpetstore研究入门 分类: java2008-12-21 23:25 561人阅读 评论(2) 收藏 举报 springstrutsibatissearchweb框架servle ...

  7. Spring Boot -01- 快速入门篇(图文教程)

    Spring Boot -01- 快速入门篇(图文教程) 今天开始不断整理 Spring Boot 2.0 版本学习笔记,大家可以在博客看到我的笔记,然后大家想看视频课程也可以到[慕课网]手机 app ...

  8. spring boot入门教程——Spring Boot快速入门指南

    Spring Boot已成为当今最流行的微服务开发框架,本文是如何使用Spring Boot快速开始Web微服务开发的指南,我们将使创建一个可运行的包含内嵌Web容器(默认使用的是Tomcat)的可运 ...

  9. Spring学习笔记(一)—— Spring介绍及入门案例

    一.Spring概述 1.1 Spring是什么 Spring是一个开源框架,是于2003年兴起的一个轻量级的Java开发框架, 由Rod Johnson 在其著作<Expert one on ...

随机推荐

  1. pandas列合并为一行

    将dataframe利用pandas列合并为一行,类似于sql的GROUP_CONCAT函数.例如如下dataframe id_part pred pred_class v_id 0 d 0 0.12 ...

  2. Spring Boot 中的静态资源到底要放在哪里?

    当我们使用 SpringMVC 框架时,静态资源会被拦截,需要添加额外配置,之前老有小伙伴在微信上问松哥Spring Boot 中的静态资源加载问题:"松哥,我的HTML页面好像没有样式?& ...

  3. SpringBoot进阶教程(二十三)Linux部署Quartz

    在之前的一篇文章中<SpringBoot(九)定时任务Schedule>,已经详细介绍了关于schedule框架的配置和使用,有收到一些朋友关于部署的私信,所以抽时间整理一个linux部署 ...

  4. JavaScript夯实基础系列(一):词法作用域

      作用域是一组规则,规定了引擎如何通过标识符名称来查询一个变量.作用域模型有两种:词法作用域和动态作用域.词法作用域是在编写时就已经确定的:通过阅读包含变量定义的数行源码就能知道变量的作用域.Jav ...

  5. 四种途径提高RabbitMQ传输消息数据的可靠性(一)

    前言 RabbitMQ虽然有对队列及消息等的一些持久化设置,但其实光光只是这一个是不能够保障数据的可靠性的,下面我们提出这样的质疑: (1)RabbitMQ生产者是不知道自己发布的消息是否已经正确达到 ...

  6. javascript小记一则:今天在写VS2005——.NET程序时,写的一个JS图片示例案例

    源码如下,如遇调试问题,可以找我解决: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quo ...

  7. 文本三剑客---awk(gawk)基础

    gawk程序是Unix中原始awk程序的GNU版本.gawk程序让流编辑器迈上了一个新的台阶,它提供了一种编程语言而不只是编辑器命令.在gawk编程语言中,可以完成下面的事情: (1)定义变量来保存数 ...

  8. PyQtdeploy-V2.4 User Guide 中文 (二)

    PyQtdeploy 用户指南 目录 介绍 与V1.0+的差异 作者 证书 安装 部署过程概览 PyQt的演示 构建演示 Android IOS Linux MacOS Windos 构建系统根目录 ...

  9. 解决将Excel表导入到SQL Server数据库时出现Text was truncated or one or more characters had no match in the target code错误

    编写python爬虫程序可以在电商.旅游等网站上爬取相关评论数据,这些数据可以用于词云制作.感情词分析.提取关键词等,也可以将爬取下来的数据以自己的方式进行展示.评论数据爬取下来后,就要考虑怎样入库, ...

  10. Android RecyclerView初探

    今天研究了一下RecyclerView,RecyclerView比ListView的效率更高而且可以横向滑动,所以现在许多Android项目更倾向与使用RecyclerView. 下面是一个Recyc ...