JavaWeb: Spring框架学习1

原创 2017年07月17日 19:42:35

Spring学习笔记

Spring是一个非常活跃的开源框架;它是一个基于Core来构架多层JavaEE系统的框架,它的主要目地是简化企业开发(Spring架构图)

Spring以一种非侵入式的方式来管理你的代码,Spring提倡”最少侵入”。使用框架一般要学习使用框架的api,但是Spring不需要(学习框架就是学习它的api)。

Spring的核心是IOC(反转控制)与AOP(面向切面编程)

 

Spring学习核心问题:

1)Spring容器是干么用的

2)如何帮助我们创建对象的?

3)创建对象的三种方式?

4)创建对象的两种时机?

5)哪种创建对象的时机比较好?

6)Spring如何管理对象的作用域和生命周期?

 

Spring配置文件:applicationContext.xml

SpringIOC(控制反转):把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期(换句话说就是,让spring容器帮助我们创建对象,这样程序员就能专注于业务逻辑的实现)。

 

如何将一个类放到Spring容器里面,让它帮助我们创建对象呢?

在配置文件applicationContext.xml中对类进行配置。将类放到Spring容器里面,这个类就是bean,id是类的唯一标识,class表示全类名。把类名给Spring容器,让它帮助我们创建对象。

 

Spring帮助我们创建对象的步骤:

1)启动Spring容器。2)把对象从Spring容器中取出来。3)调用对象中的方法。

都是有模板性代码的,不需要关心对象是怎么创建的,关注于业务逻辑的处理就可以了。

 

Spring创建对象的三种方式?

1)调用默认的构造函数进行创建对象:如果写了有参数的构造函数,因为找不到无参数的函数,就会报错。

2)利用静态工厂的方式创建对象:Spring调用工厂方法创建对象,但是真正创建对象还是程序员来完成的。

3)实例工厂方法。

在Spring的配置文件中,只要是bean节点,Spring就会为该bean创建对象。

 

Spring创建对象的时机?在单例模式下(Scope)

1)默认情况下,启动Spring容器时创建对象

2)在调用getBean()方法的时候创建对象。


在spring的配置文件bean中有一个属性lazy-init="default/true/false"

a、如果lazy-init为"default/false"在启动spring容器时创建对象。

b、如果lazy-init为"true",在context.getBean时才要创建对象。

在多例的情况下,调用getBean()方法时,创建对象。

 

哪种创建对象的时机比较好?

第一种情况下,可以在启动spring容器的时候,检查spring容器配置文件的正确性,如果再结合tomcat, 如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了内存中,如果有数据,则对内存来是一个消耗(对象的生命周期变长了)。

第二种情况下,可以减少内存的消耗,但是不容易发现错误。

 

spring的bean中的scope

1、由spring产生的bean默认是单例的(可以实现数据共享)

2、可以在spring的配置文件中,scope的值进行修改="singleton/prototype"

3、如果spring的配置文件的scope为"prototype",则在得到该getBean()时才创建对象。

 

spring容器对对象生命周期的管理:

1、Spring容器创建对象

2、执行init方法

3、调用自己类的方法

4、当Spring容器关闭的时候执行destroy方法(此时对象销毁),如何关闭Spring容器呢。

 

Spring DI:依赖注入:给对象的属性赋值

1、利用set方法给属性赋值;property用来描述一个类的属性,并且对类的属性进行赋值,在bean节点下面。

1)、基本类型的的封装类,String等类型通过value进行赋值。

2)、引用类型通过ref进行赋值。

注意:一个类中的属性都可以采用SpringID的方式进行赋值,但是一般不常用,这种方式主要用于特定场合。

Spring容器会解析bean节点下的所有property对象,解析name和value,然后通过调用set方法进行赋值。


2、利用构造函数给属性赋值

SpringID的说明:如果Spring配置文件中的bean中没有<constructor-arg>元素,则调用默认的构造函数;如果Spring的配置文件中有<constructor-arg>元素,则该元素是唯一确定的构造函数。

index代表参数的位置,从0开始计算。

type表示参数的类型 java.lang.String。

value 给基本类型赋值。

ref给引用类型赋值。

 

SpringIOC和DI的意义:实现了完全的面向接口编程

 

利用springIOC和DI实现MVC的模拟例子:

把接口放到Spring容器中(配置文件中没有意义的)

SpringInit类的作用

 

Spring注解:说明(可以少写一些代码)

1)在java中注解就是为了说明某一部分的作用

2)注解都可以用于哪里是@Target注解起的作用。

3)注解可以标注在ElementType枚举类所指定的位置。

4)用来解析注解的类成为注解解析器。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <context:component-scan base-package="main.com.tniu"/>

    <!--引用另一个配置文件-->
    <import resource="applicationContext_create.xml"/>

    <!--在Spring容器中注册,lazy-init用于标记在在什么时候创建对象-->
    <bean id="Student" class="main.com.tniu.Student" lazy-init="default"/>

    <!--lazy-init懒加载,在调用getBean方法的时候创建对象-->
    <bean id="Teacher" class="main.com.tniu.Teacher" lazy-init="true"/>

    <!--通过静态工厂创建对象,factory-method表示调用那个工厂方法帮组我们创建对象-->
    <bean id="ObjectFactory" class="main.com.tniu.ObjectFactory" factory-method="getInstance"/>

    <!---->
    <!--配置Scope,默认是单例模式singleton,prototype表示多例的-->
    <bean id="SingleEntity" class="main.com.tniu.SingleEntity" scope="prototype"/>

    <!--对象的初始化和销毁:init-method,destroy-method-->
    <bean id="InitAndDestroy" class="main.com.tniu.InitAndDestroy" init-method="init" destroy-method="destory"/>

    <!--通过set方法给属性赋值-->
    <bean id="TestSetMethod" class="main.com.tniu.TestSetMethod">
        <property name="id" value="1"/>
        <property name="name" value="陈如水"/>
        <property name="student" ref="Student"/>
        <!--通过对list集合进行赋值-->
        <property name="lists">
            <list>
                <value>list1</value>
                <ref bean="Student"/>
                <value>list2</value>
            </list>
        </property>
        <!--对property集合进行赋值-->
        <property name="prop">
            <props>
                <!--只能是字符串类型-->
                <prop key="k1">
                    test
                </prop>
                <prop key="k2">
                    test2
                </prop>
            </props>
        </property>
        <!--对set集合进行赋值-->
        <property name="sets">
            <set>
                <value>test</value>
                <ref bean="Student"/>
                <value>set1</value>
            </set>
        </property>
        <!--对map集合进行赋值-->
        <property name="map">
            <map>
                <entry key="key1">
                    <value>v1</value>
                </entry>
                <entry key="key2">
                    <value>v2</value>
                </entry>
            </map>
        </property>
    </bean>

    <bean id="ConstructorEntity" class="main.com.tniu.ConstructorEntity">
        <!--一定要和构造函数中参数的位置对应,在这里犯过错-->
        <constructor-arg index="0" type="java.lang.String" value="陈如水"/>
        <constructor-arg index="1" type="main.com.tniu.Student" ref="Student"/>
        <constructor-arg index="2" type="java.lang.Long" value="11"/>
    </bean>
</beans>


package main.com.tniu;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by Administrator on 2017/7/11.
 */
public class Test {
    /**
     * Spring帮助我们创建对象的过程
     * ApplicationContext
     * ClassPathXmlApplicationContext
     */
    @org.junit.Test
    public void testSpring() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) context.getBean("Student");
        student.sayHello();
    }
    
    /**
     * 主配置文件引用另一个配置文件
     */
    @org.junit.Test
    public void testImport() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) context.getBean("Person");
        person.sayPerson();
    }

    /**
     * 通过别名获取对象
     */
    @org.junit.Test
    public void testAlias() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) context.getBean("alias");
        person.sayPerson();
    }

    /**
     * 容器启动的时候创建对象
     */
    @org.junit.Test
    public void testCreateObject() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("容器启动的时候创建对象");
        Student student = (Student) context.getBean("Student");
        student.sayHello();
        //打印顺序:通过构造方法创建对象--->容器启动的时候创建对象
    }

    /**
     * 调用getBean()的时候创建对象
     */
    @org.junit.Test
    public void testCreateObjectTwo() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("getBean创建对象");
        Teacher teacher = (Teacher) context.getBean("Teacher");
        teacher.sayHello();
    }

    /**
     * 创建对象的方式,Spring容器通过调用构造方法获取对象
     * 通过静态工厂创建对象
     * 需要把静态工厂类加入到配置文件当中
     */
    @org.junit.Test
    public void createMethod() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //直接转化成Student类
        Student student = (Student) context.getBean("ObjectFactory");
        student.sayHello();
    }

    /**
     * Spring帮助我们创建的对象是不是单例的?
     * 如果是单例的,就存在数据共享(对象中的成员变量和成员方法)
     * 两个对象的内存地址值是一样的,说明是单例的;
     * 如何去验证数据共享呢
     * 如果修改bena中的Scope属性为prototype,则变成多例的,地址值是不一样的
     * 注意:如果设置Scope属性为prototype,则对象是在调用getBean()方法的时候创建,在使用Struct2的时候
     * action的创建必须是多例的,并且需要在容器启动的时候创建,所以要用到scope属性。
     */
    @org.junit.Test
    public void testSingle() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) context.getBean("Student");
        System.out.println(student);
        student.getList().add("a");
        Student student1 = (Student) context.getBean("Student");
        student1.getList().add("b");
        System.out.println(student1);
        //打印集合的长度,结果为2
        System.out.println(student1.getList().size());
    }

    /**
     * 初始化方法和销毁方法的调用
     * 对象的生命周期
     * 如何关闭Spring容器 close()方法
     */
    @org.junit.Test
    public void testInitAndDestroy() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        InitAndDestroy initAndDestroy = (InitAndDestroy) context.getBean("InitAndDestroy");
        //打印结果:构造方法--->init方法
        ClassPathXmlApplicationContext app = (ClassPathXmlApplicationContext) context;
        app.close();
    }

    /**
     * 通过set方法给类的属性赋值
     * 没有能打印出结果
     */
    @org.junit.Test
    public void testSetMethod() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        TestSetMethod testSetMethod = (TestSetMethod) context.getBean("TestSetMethod");
        testSetMethod.toString();
    }

    /**
     * 通过构造函数进行赋值
     * 可以进行正常的打印
     */
    @org.junit.Test
    public void testSetMethodCon() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ConstructorEntity con = (ConstructorEntity) context.getBean("ConstructorEntity");
        System.out.println(con.getName());
        System.out.println(con.getStudent());
        System.out.println(con.getId());
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Spring框架自学之路——简易入门

目录目录 介绍 Spring中的IoC操作 IoC入门案例 Spring的bean管理 Bean实例化的方式 Bean标签的常用属性 属性注入 使用有参构造函数注入属性 使用set方法注入属性 注入对...
  • qq_15096707
  • qq_15096707
  • 2017年06月01日 00:02
  • 9975

spring学习之spring框架介绍

spring学习之spring框架介绍开始spring如果你是刚使用spring的开发人员,可以先使用spring-boot来创建一个spring应用。他基于spring框架。主张约定优于配置。被设计...
  • a291382932
  • a291382932
  • 2016年10月21日 01:18
  • 774

spring框架学习过程的小知识

spring框架学习过程中的小知识及问题汇总
  • jinzhencs
  • jinzhencs
  • 2015年12月09日 14:57
  • 505

【Spring框架学习】:初识Spring框架

软件框架        框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定 义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后...
  • erlian1992
  • erlian1992
  • 2016年12月23日 21:18
  • 2810

spring框架学习(一)

1,什么是spring框架 spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,...
  • lishuangzhe7047
  • lishuangzhe7047
  • 2014年03月07日 22:51
  • 451533

Spring 框架知识点汇总

1、 标签 Spring MVC的配置方案,标签会自动注册下列的4个bean: 1) AutowiredAnnotationBeanPostProcessor 对应于使用@AutoWired注解 2...
  • promaster
  • promaster
  • 2015年03月18日 13:38
  • 778

深入学习Spring框架之一Spring的简要概括

Java开发的春天 Spring框架最初的形成,来自于最初的一位Java领域的大牛-----Rod Jahnson。这位大牛所著的一本叫做《Expert One-on-One J2EE Design...
  • lycyl
  • lycyl
  • 2016年09月06日 11:28
  • 1637

JavaWeb: Spring框架学习2(注解)

1,使用Spring IOC与DI实现MVC的模拟例子:  spring配置文件 ...
  • chenrushui
  • chenrushui
  • 2017年09月01日 17:27
  • 114

Spring学习笔记 依赖注入

依赖注入简介依赖注入是一个很常用的词。Java新手常会写出如下的代码,直接在写一个类的时候让它自己初始化自己。但是这不是一个好办法。一个类的状态应该由创建它的类决定,不能由自己决定自己。因此更好的办法...
  • u011054333
  • u011054333
  • 2017年01月15日 00:52
  • 449

新手入门:Spring的一些学习方法及意见

Spring简介: 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架...
  • Prepared
  • Prepared
  • 2017年01月04日 07:36
  • 3621
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JavaWeb: Spring框架学习1
举报原因:
原因补充:

(最多只允许输入30个字)