Spring第一阶段

Spring

学习路线

  • Spring 的第一天:Spring 的IOC的入门,Spring整合web项目
  • Spring的第二天:IOC的注解开发,Spring的AOP的xml开发
  • Spring的第三天:Spring的Aop的注解开发,Spring的事务管理
  • ssh 的整合

Spring的概述

什么是Spring

Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson创建,简单来说,Spring是一个分层的javaEE/EEfull-stack(一站式) 轻量级开源框架

  • Spring是SE/EE的一站式框架:Spring有EE开发中每一层解决的方案。
  • EE的三层结构:
    • WEB层:Spring MVC
    • 业务层:Spring的Bean管理,声明式事务
    • 持久层:Spring的JDBC的模板,Spring的ORM模块

Spring的优点:

Spring的版本

Spring3.X Spring4.X

Spring的IOC的入门

IOC(Inversion of Control)

IOC:控制反转,将对象的创建权反转给Spring。

  • 解决程序的耦合性

Spring的入门

  • 第一步:下载Spring的开发包
    • 官网: spring 下载spring-framework-4.2.4.RELEASE-dist.zip
    • 解压:Spring的开发包
      • docs
      • libs
      • schema
  • 第二:导包:只需要导红色圈里的那几个就行,还有log4j的一个包,跟一个日志的接口包commons-logging

  • 第三:编写接口跟实现类
1
2
3
4
5
6
7
8
9
public interface UserDao {
   public void sayHello();
}
public class UserDaoImpl implements UserDao {
   @Override
   public void sayHello() {
        System.out.println("Hello Spring Demo1...");
   }
}
  • 第四:创建一个Spring的核心配置文件:
    • 在src下创建 applicationContext.xml 名字可以变
    • 引入约束
1
2
3
4
5
6
7
8
9
10
11
12
//约束在spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    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.xsd">
.............................
</beans>
  • 编写Spring配置文件
1
<bean id="userDao" class="路径"></bean>
  • 第五:编写测试类
    //Spring的方式:IOC的底层实现:工厂+反射+配置文件
1
2
3
4
5
6
public void demo2(){
  ApplicationContext addli= new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao=(UserDao) appli.getBean("userDao");;
  userDao.sayHello();
}

DI

DI:依赖注入。需要有IOC的环境

  • IOC和DI的区别:
    • IOC:控制反转:将对象的创建权交给Spring
    • DI:Spring在创建过程中,将类依赖的属性注入进来
1
2
3
4
5
6
//现在要配置的类中创建属性,并提供set方法
//然后再在配置文件中配置
<bean id="UserDao" class="UserDao路劲">
    //注入属性
    <property name="name" value="李四"/>
</bean>

Spring的工厂类的概述

BeanFactory

  • BeanFactory是Spring 早期的工厂类,现在已经不用了
  • BeanFactory在调用getBean()的时候才会创建类的实例。

ApplicationContext

  • ApplicationContext是Spring目前使用的工厂类
  • ApplicationContext支持比BeanFactory更加强大的功能(国际化)
  • ApplicationContext在加载Spring的配置文件的时候,就会创建类的实例

  • ApplicationContext下有两个实例:

    • ClassPathXmlApplicationContext加载类路劲下的配置文件
    • FileSystemXmlAppliocationContext :加载本地硬盘上的配置文件

Spring的常见的配置

<bean id="" class="" scope="" init-method="方法名" destory-method="方法名" />

  • 后边的两个可以省略

Id和name的配置

  • id:用到了唯一的约束,都不要使用相同名称的值。Id中不能使用特殊字符
  • name:没有使用唯一的约束,都不要使用相同名称的值。name中可以使用特殊字符。
    • id跟name中如果有相同的值,运行时会报错。

在Struts1框架中,Action交给Spring管理
<bean name="/login" class="xxx"> 因为有/所以只能用name。

scope的配置:Bean作用范围

  • singleton :默认值,单例的,在一个方法中不管创建多少次,都是同一个对象。
  • prototype :多例的。
  • request :在Web项目中使用,创建一个类,保存到request域中。
  • session :在web项目中使用,创建一个类,保存到session中。
  • globalsession:在web项目中使用,而且Prolet环境,就是例如登陆了百度,就能访问百度云啊贴吧啊什么的。

bean的生命周期的配置(可以省略)

初始化方法跟销毁方法都是要在UserDao类中定义的。

  • init-method=”方法名” :Bean被创建的时候要去执行的方法
  • destory-method=”方法名” :Bean被销毁的时候要去执行的方法
    • Bean 的创建必须是单例的,而且必须是关闭工厂ClassPathXmlApplicationContext对象.close()

配置不联网提示

  • windows属性 —> xml catalog —> 约束中的最后一个地址复制过来到key,上面选择本地中的spring-framework-4.2.4.RELEASE\schema\beans\4.2的那个,中间选择key typeSchema location

Spring的Bean管理的xml的方式

Spring的Bean的创建

Spring中提供了三种Bean的实例化的方式:

  • 无参构造的方式
1
2
3
4
5
6
7
8
//bean类
public class bean{
   public bean(){
      syso("无参构造被调用");
   }
}
//配置文件
<bean id="bean" class="bean的地址">
  • 静态工厂实例化的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//bean类
public class bean{
}
//静态工厂类
public class beanFactory{
   public static Bean createBean(){
      syso("静态工厂执行了");
      return new Bean();
   }
}
//配置文件
<bean id="bean" class="beanFactory的地址" factory-method="createBean">
  • 实例工厂实例化的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//bean类
public class bean{
}
//实例工厂类
public class beanFactory{
   public Bean createBean(){
      syso("实例工厂执行了");
      return new Bean();
   }
}
//配置文件
<bean id="beanFactory" class="beanFactory的地址" />
<bean id="bean" factory-bean="beanFactory" factory-method="createBean" />

Bean的属性注入

Bean的属性注入

    1. 构造方法的方式
    1. set方法的属性注入
    1. 接口注入的方式
1
2
3
4
5
6
7
8
9
10
public interface Injection{
   public void setUsername(String username);
}
class User implements Injection{
  private String username;
  public void setUsername(String username){
     this.username=username;
  }
}

Spring的Bean的属性注入

Spring 中只支持前两种:

  • 构造函数:
1
2
3
4
5
6
7
//配置文件,当然前提是有这个实体类跟有参构造函数
<bean id="car" class="car的路劲" >
   <constructor-arg name="" value="" />
   <constructor-arg name="" value="" />
</bean>
//构造注入中的<constructor-args name="">
name也可以换为index,从0开始表示第一个构造方法中的值是什么
  • set方法
1
2
3
4
5
//配置文件,当然前提是有这个实体类跟set方法
<bean id="car2" class="com.itheima.spring.demo4.Car2">
   <property name="name" value="宝马/>
   <property name="price" value="800000"/>
</bean>
  • set中如果有对象的话
1
2
3
4
<bean id="people" class="people的路劲" >
   <constructor-arg name="正常的属性名" value="正常的属性值" />
   <constructor-arg name="正常的属性名" ref="前面配置文件的id这里用car" />
</bean>
Spring2.5版本之后提供p名称空间的属性注入
  • 引入p名称空间:xmlns:p="http://www.springframework.org/schema/p"
  • 完成属性注入:
    • 格式:
      • 普通属性 p:属性名=“属性值”
      • 对象类型的属性 p:属性名-ref=“其他属性的id或name”
1
2
3
4
5
//普通
<bean id="car" class="car路劲" p:name="" p:price="" />
//对象类型的
<bean id="people" class="people的路劲" p:name="" p:car-ref="car" />
Spring3.X版本之后提供的 spEL 的属性注入:
  • spEL:Spring Expression Language
    • /#{}
1
2
3
4
5
6
7
8
9
10
11
//普通类型
<bean id="car" class="">
   <property name="name" value="#{'奔驰'}">
   <property name="price" value="#{123}">
</bean>
//对象类型
<bean id="employee" class="">
   <property name="name" value="#{'强强'}">
   <property name="car" value="#{car}">
</bean>
  • 还能用另外一个类的属性或方法名来赋值,先创建这个类,要用属性的话,可以直接写get方法,不用定义成员变量的。
    • 要想用哪个类中的方法,就得先实例化这个类
    • 然后再 #{实例化类名.属性/方法} 就可以了

//定义要使用的类

1
2
3
4
5
6
7
8
9
10
public class CarInfo {
    //public String name;
    public String getName() {
        return "奔驰";
    }
    
    public Double calculatePrice(){
        return Math.PI * 100000;
    }
}

复杂类型的属性注入

list map propertise 等复杂的属性类型

  • list/数组
1
2
3
4
5
6
7
8
9
10
//如果list的是对象最里边可以用<ref/>
<bean id="" class="" >
   <property name="lists">
      <list>
        <value>值</value>
        <value>值</value>
        <value>值</value>
      <list>
   </property>
</bean>
  • map
1
2
3
4
5
6
7
8
//如果map里边是对象<entry key-ref="" value-ref=""/>
<bean id="" class="" >
   <property name="maps">
      <map>
        <entry key="" value="" />
      <map>
   </property>
</bean>

map还有一种方式
需要生成set方法,并在map标签中添加 <entry> <key> <value>test1</value> </key> <value>AAA</value> </entry>

  • propertise,键值对的形式
1
2
3
4
5
6
7
<bean id="" class="" >
   <property name="props">
      <props>
        <props key="">值</props>
      <props>
   </property>
</bean>

Spring的分模块开发

就是可能有两个配置文件,分别配置不同的类

  • 可以在加载配置文件时加载两个配置文件,用 隔开
  • 也可以只加载一个配置文件,然后在其中引入另外一个配置文件
    • <import resource="applicationContext2.xml">
      • 如果引入的配置文件中的id有跟原配置文件的id相同的值,则会覆盖原来的。

案例中出现的问题

将Dao配置到Spring

  • 可以在配置service方法的时候把,Dao当作一个属性来配置,先把customerDao实例化,然后再引入到service配置文件中:
1
2
3
4
5
6
<bean id="customerService" class="com.itheima.crm.service.impl.CustomerServiceImpl">
    <property name="customerDao" ref="customerDao"/>
</bean>
<bean id="customerDao" class="com.itheima.crm.dao.impl.CustomerDaoImpl">
</bean>

配置监听器,使每次获取的都是同一个工厂类

  • 为了避免每次用的时候,都创建一个工厂类,用监听器,在服务器启动的时候就让创建了工厂了,并存在ServletContext中,以后直接用就行
    • 先引一个Spring的jar包:spring-web-4.2.4.RELEASE.jar
    • 包中已经配好了监听器,直接配置就行:

在web下配置监听器

1
2
3
4
5
6
7
8
9
 <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>

获得工厂:

1
2
3
4
5
6
7
8
9
//保存客户的方法:save
public String save(){
   //调用业务层,使用包中封装好的工具类获得servletContext中的工厂类
   WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext_());
   CustomerService customerService = (CustomerService)   applicationContext.getBean("customerService");
   customerService.save(customer);
   return NONE;
}

张冲 wechat
欢迎扫一扫上面的微信关注我,一起交流!
坚持原创技术分享,您的支持将鼓励我继续创,点击打赏!