spring 基础一

1 介绍一下spring:

  • spring管理你的业务对象,“一站式”解决方案,并贯穿表现层springmvc、业务层及持久层spring j dbc,与其他框架无缝结合。

  • Spring框架是一个为Java应用程序的开发提供了综合、广泛的基础性支持的Java平台。Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。Spring框架本身亦是按照设计模式精心打造,这使得我们可以在开发环境中安心的集成Spring框架,不必担心Spring是如何在后台进行工作的。

  • Spring框架至今已集成了20多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。

  • Spring是一个一站式的解决框架,对我们web开发当中的各个层级都有对应的解决方案。

2 spring的优缺点:

优点:高内聚低耦合
    1.方便解耦,简化开发

sping就是一个大工厂,可以将所有的对象创建和依赖关系维护,交给sprong管理

    2.AOP编程的支持

Spring提供面向切面编程,可以方便的实现对程序进行权限拦截,运行监控等功能

    3.声明式事务的支持

只需要通过配置就可以完成对事务的管理,不用动手编程

    4.方便程序的测试

Spring对Junit4支持,可以通过注解方便的测试Spring程序

    5.方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如: Struts, Hibernate, Mybatis, Quartz 等)的直接支持

    6.降低JavaEE API的使用难度

Spring对JAvaEE开发中非常难用的一些API (JDBC, javaMail,远程协调_,都提供了封装,是这些API应用难度大大降低

    7.IOC和DI

大大降低程序的耦合性,促进了低耦合,简化了开发


  • 缺点:
    1.增加一定复杂度
    2.依赖spring容器重
    3. 配置文件比较多,配置比较复杂

3 Spring的架构体系

spring的架构体系

Test:测试模块,spring可以与我们的junit进行整合做测试非常方便

Core  container :核心容器,就是用来装javaBean对象。

AOP:切面编程

Aspects:切面编程应用的一个模块,与我们aop共同组成spring当中的切面编程

Data Access:数据访问

Web:对数据访问的支持

Transactions:用于支持我们的事物处理。用于解决我么业务层的事物处理问题

Messaging: 消息队列

4 spring第一大特性 控制反转 IOC : 创建对象

4.1 IOC:

inversion of controller 控制反转,什么是控制反装:就是将创建对象的过程或者说创建对象的权限交给了spring框架来帮我们处理,我们再不用通过new的方式来创建Javabean对象,这个过程就叫做控制反转, 通过spring容器主动创建对象,就是通过反射来创建对象。

4.3 IOC与DI的区别与联系

  • IOC是创建我们的对象
  • DI就是为我们对象中的属性赋值
  • DI依赖于IOC,只有我们先创建对象,才能个属性赋值

5 spring第二大特性 DI 依赖注入: 给属性赋值

DI:dependency injection 依赖注入,就是创建对象之后,给属性赋值的过程就叫做DI,说白了就是通过配置来给属性赋值

  • IOC与DI的关系:先创建对象,然后才有可能通过DI来进行赋值
  • DI是属性赋值,依赖于对象的创建,也就是依赖于IOC。

5.1 第一种属性赋值: 通过set 方法进行属性赋值

属性的类型一定要匹配

    <bean id = "date" class = "java.util.Date"></bean>

    <bean id = "dog" class = "com.hzh.demo4.Dog">
        <property name = "name" value = "金毛"></property>
        <property name = "age" value = "4"></property>
        <property name = "color" value = "红色"></property>
    </bean>

    <bean id = "PersonProperty" class="com.hzh.demo4.Person">
        <property name="name" value = "张三"></property>
        <property name="age" value = "4"></property>
        <property name = "dog" ref = "dog"></property>
        <property name = "date" ref = "date"></property>
    </bean>

5.2 第二种属性赋值: 通过构造器(有参)给属性赋值

无参 有参 都给

    <bean id = "tom" class = "com.hzh.demo5.Tom">
        <constructor-arg name = "color" value = "蓝色"></constructor-arg>
        <constructor-arg name = "name" value = "汤姆猫"></constructor-arg>
        <constructor-arg name = "age" value = "12"></constructor-arg>
        <constructor-arg name = "jerry" ref = "jerry"></constructor-arg>
    </bean>

    <bean id = "jerry" class = "com.hzh.demo5.Jerry">
        <constructor-arg name = "name" value = "小老鼠"></constructor-arg>
        <constructor-arg name = "age" value = "2"></constructor-arg>
    </bean>

5.3 给集合属性 List 赋值

    <bean id = "collectProperty" class = "com.hzh.demo6.CollectProperty">
        <property name = "lists">
            <list>
                <value>张三</value>
                <value>list</value>
                <value>123</value>
                <value type = "java.lang.Integer">456</value>
                <value>"lisi"</value>
                <!--对象的引用-->
                <ref bean="tom"/>
            </list>
        </property>
    </bean>

5.4 给集合属性 List 赋值

    <bean id = "collectProperty" class = "com.hzh.demo6.CollectProperty">
        <property name = "lists">
            <list>
                <value>张三</value>
                <value>list</value>
                <value>123</value>
                <value type = "java.lang.Integer">456</value>
                <value>"list"</value>
                <ref bean="tom"/>
            </list>
        </property>
        <property name="maps">
            <map>
                <entry key = "张三" value= "123"></entry>
                <entry key = "list" value-ref= "jerry"></entry>
                <!--字符串 = 对象-->
                <entry key = "lists" value-ref= "tom"></entry>
                <!--字符串 = 对象-->
                <entry key-ref = "jerry"  value-ref= "tom"></entry>
                <!--对象 = 字符串-->
                <entry key-ref = "jerry" value= "王五"></entry>
            </map>
        </property>
    </bean>

5.5 给集合属性 set 赋值

        </property>
            <property name="sets">
            <set>
                <value>张三</value>
                <value>123</value>
                <value>123</value>
                <ref bean="dog"/>
                <ref bean="dog"/>
            </set>
        </property>

5.6 给集合属性Property赋值

        <!--注意properties的属性赋值只能写字符串 -->
        <property name="properties">
            <props>
                <prop key="list">34</prop>
                <prop key="zhangsan">12</prop>
                <prop key="中国">首都北京</prop>
            </props>
        </property>

6 核心容器 Core container :核心容器,就是用来装javaBean对象的容器。

spring容器

6.1 获取容器的三种方式:

  • 1 使用ClassPathXmlApplicationContext获取容器类,ApplicationContext 是我们容器的一个子接口
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserDao dao = (UserDao) context.getBean("userDao");
  • 2 XmlBeanFactory来获取容器类,已过时
    XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
    UserDao dao = (UserDao) factory.getBean("userDao");
  • 3 使用FileSystemXmlApplicationContext来获取容器,需要传入spring配置文件的绝对路径
    可以使用外部的配置文件
    FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("F:\\workspace_myProject\\springDemo\\src\\main\\resources\\applicationContext.xml");
    UserDao dao = (UserDao)context.getBean("userDao");

7 Java Bean

7.1 IOC 创建Java Bean 的三种方式

在配置文件加载完成之后就会创建配置的全部的JavaBean,并且放入到容器中
注意: 在创建Java Bean对象的时候对对象进行初始化,执行初始化方法
  • 1 通过无参构造的方式创建:
    • 条件: 必须有无参构造
    <bean id = "createBean" class="com.hzh.springbean.UserBeanFactory">
    </bean>
  • 2 通过静态工厂方式创建对象
    • factory-method :工厂类的静态方法.必须用static修饰
    • 静态方法必须有返回值
    • class: 工厂类的相对路径
<   !-- 通过静态工厂创建对象 -->
    <bean id = "userBean2Factory" class = "com.hzh.springbean.UserBeanFactory2" factory-method="getFactory"></bean>
  • 3 通过实例工厂获取javaBean
    • 工厂类的方法不需要static修饰
    • factory-bean: 为工厂类对象
    • factory-method: 为工厂类的方法.
    • 第二个class : 返回对象类的相对路径
    <!-- 通过实例工厂获取javaBean -->
    <!-- 创建实例工厂 -->
    <bean id = "userBean3Factory" class ="com.hzh.springbean.UserBean3Factory" ></bean>
    <!-- 通过已经申明的工厂来获取我们的javaBean对象 -->
    <bean  id = "userBean3" class = "com.hzh.springbean.UserBeanFactory2" factory-bean="userBean3Factory" factory-method="getBean2"></bean>

静态工厂和实例工厂的区别就是方法有没有静态修饰

使用默认构造可以直接获取某一个javaBean的对象
通过静态工厂和实例工厂则可以一个工厂提供不同的JavaBean对象,只需要选择相对应的工厂方法即可.

7.2 Spring Bean的作用域与作用范围

Bean的作用域范围有四种:

singleton 单列 默认 :

创建一个对象,每次调用,都使用这个对象
这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。

prototype 多例 :

每次调用都会创建一个新的实例 ,为每一个bean请求提供一个实例。

Request:

适用于web开发当中,将我们的对象存储在request域中

Session:

适用于web开发当中,将我们的对象存储在session中

7.3 java Bean 的生命周期

  • 可以配置init-method与destroy-method来实现bean的初始化和关闭的时候调用指定的方法

  • Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。

    Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。
    初始化之后调用的回调方法。
    销毁之前调用的回调方法。

  • Spring框架提供了以下四种方式来管理bean的生命周期事件:

    • InitializingBean和DisposableBean回调接口
      • 针对特殊行为的其他Aware接口
      • Bean配置文件中的Custom init()方法和destroy()方法
      • @PostConstruct和@PreDestroy注解方式

      • 使用customInit()和 customDestroy()方法管理bean生命周期的代码样例如下:

<bean id = "userDemo" class="com.hzh.User" init-method="initMethod" destroy-method="destoryMethod"></bean>

如果要销毁一个方法,则使用 ClassPathXmlApplicationContext类的对象调用 .close()即可

7.4 BeanFactory和ApplicationContext有什么区别?

  • ①ApplicationContext 接口继承BeanFactory接口,Spring核心工厂是BeanFactory ,BeanFactory采取延迟加载,第一次getBean时才会初始化Bean, ApplicationContext是会在加载配置文件时初始化Bean。

  • ②ApplicationContext是对BeanFactory扩展,它可以进行国际化处理、事件传递和bean自动装配以及各种不同应用层的Context实现

    • ③从表面上看,application context如同bean factory一样具有bean定义、bean关联关系的设置,根据请求分发bean的功能。但application context在此基础上还提供了其他的功能。

      • 提供了支持国际化的文本消息
      • 统一的资源文件读取方式
      • 已在监听器中注册的bean的事件

7.5 Spring通过配置文件和注解的方式创建javaBean对象的比较

  • 自己写的java类,建议全部用注解的方式
  • Jar包中的类,全部用配置文件的方式

8 spring 与 WEB的整合

8.1 Spring为什么要与我们的javaWeb整合???

我们是从spring容器中取出对象,那么我们每请求一个java Bean 对象,就要创建一个spring容器吗?,每创建一个spring容器,就要在jvm中开辟出一块空间,分配地址,这样会浪费我们的jvm资源,我们可不可以让spring容器之创建一次?

整合思路:在我们创建javaWeb容器的时候,就会创建一个ServletContext对象,并且这个对象是唯一的,单例的,直到javaWeb容器关闭的时候,才会销毁。
那么问题来了,我们可不可以监听ServletContext的启动,如果监听到ServletContext的启动,我们马上就去启动我们的spring容器,也就是说,ServletContext只启动一次,我们的spring容器也只启动一次,将spring容器启动成功之后,就把我们的spring容器放到ServletContext对象当中,以后需要使用spring容器,再不用自己去new了,直接从ServletContext当中获取即可

8.2 导入jar

<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

8.3 监听ServletContext的创建

  • 在WEB-INF下的web.xml中配置监听器:
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

8.4 定义自己的servlet,在servlet请求中获取spring容器

这里写图片描述

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1 获取servletContext对象
        ServletContext servletContext = request.getServletContext();

        //2 从servletContext中取出spring容器,
        WebApplicationContext attribute = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

        //3 获取javaBean对象
        Dog bean = (Dog) attribute.getBean("dog");
        System.out.println("小狗的名字: "+bean.getName());

        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

8.5 设置访问路径,访问

如果使用tomcat插件,配置了 :

    <path>/</path>

则访问时不用写项目名: http://localhost:8080/ContextSerlvet



9 spring注解的使用

9.1 导入jar包

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

9.2 开启注解

    <!-- 开启注解 -->
    <context:annotation-config></context:annotation-config>

9.3 开启包扫描

    <!-- 包扫描 -->
    <context:component-scan base-package="com/hzh/demo8"></context:component-scan>

9.4 使用注解

/**
 * @Value("张三"):简单类型的注入
 * 
 * @Autowired : 复杂属性的注入,会直接去spring容器中找注入的对象,不用关心 (value = "?"),即不用考虑类的ID.
 * 
 * @Autowired+@Qualifier(value = "cat") :无论类名上面有没有ID,(value = "?")必须有,类名有ID,?=类名ID,类名无ID,?=类名首字母小写
 * 
 * @Resource : 可以写ID,也可以不写ID,
 *  
 * @Resource(name = "cat"): 如果写ID,则要与我们类名的ID保持一致.
 */
  • @Component == @Controller == @Service ==@Repository

  • @Controller 用于我们的数据展现层

  • @Service 用于我们的业务逻辑层

  • @Repository 用于我们的到层

  • @Value 用于我们简单类型属性的赋值



10 spring与junit的整合

10.1 导入jar包

<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.2.4.RELEASE</version>
    <scope>test</scope>
</dependency>

10.2 在我们的测试类上添加两个注解,并且指定我们的配置文件所在的位置

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext-web.xml")

猜你喜欢

转载自blog.csdn.net/weixin_42430194/article/details/81006591