Spring4.3.8学习[一]

如果转载文章请注明出处, 谢谢 !
本系列文章是学习完 Spring4.3.8 后的详细整理, 如果有错误请向我指明, 我会及时更正~😝

Spring4.3.8

Spring意思是春天, 于2003 年兴起的一个轻量级的Java开源框架,由Rod Johnson(音乐博士) 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。
框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
它以IoC(控制反转)和AOP(面向切面编程)两种先进的技术为基础,完美的简化了企业级开发的复杂度。

1. Spring 架构图

Spring.png

2. 开发 Spring 所需要的工具

2.1 Spring 的 jar 包

下载 Spring jar包地址

  1. Spring 核心功能(CoreContainer): spring-core, spring-beans, spring-context, spring-expression, commons-logging

不同功能需要依赖不同 jar 包, jar 包详解地址

2.2 Spring 配置文件

默认情况下命名为 applicationContext.xml ,可以建立多个 xml 文件.


xml

3. Spring 基本功能详解

3.1 SpringIoC

Spring的控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做。 由spring容器控制对象的生命周期。
IoC : Inverse Of Control(控制反转)

  1. 把自己 new 的东西改为由容器提供

    a) 初始化具体值

    b) 装配
  2. 好处:灵活装配

3.2 Spring 容器内部对象

3.2.1创建对象的方式

3.2.1.1 无参构造函数

public class HelloWorld {
    public  HelloWorld(){
        System.out.println("spring 在默认的情况下,使用默认的构造函数");
    }
    public void sayHello(){
        System.out.println("hello");
    }
}
<!-- 
   一个bean就是描述一个类
   id就是标示符
   命名规范:类的第一个字母变成小写,其他的字母保持不变
   class为类的全名
-->
     <bean id="helloWorld" class="com.lanou.domain.HelloWorld"></bean>

 @Test
    public void testHelloWorld(){
        //启动spring容器
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        //从spring容器中把对象提取出来
        HelloWorld helloWorld=(HelloWorld)context.getBean("helloWorld");
        helloWorld.sayHello();
    }

3.2.1.2 有参构造函数

public class Person {
    private String name;
    private int age;
    private String gender;
    
    public Person(String name, int age, String gender) {
        System.out.println("使用有参构造函数");
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
<bean id="person" class="com.lanou.domain.Person">
    <!--根据参数名称注入-->
    <constructor-arg name="name" value="大老王"/>
    <!--根据索引index注入-->
    <constructor-arg index="1" value="24"/>
    <!--根据构造器参数的类型-->
    <constructor-arg type="java.lang.String" value="men"/>
</bean>
public void iocPersonTest() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) context.getBean("person");
        System.out.println(person);
    }

3.2.1.3 静态工厂

public class HelloWorldFactory {
    public static HelloWorld getInstance(){
        return new HelloWorld();
    }
}
<!--静态工厂
     静态方法,静态方法不需要实例化对象,
   class指定的就是工厂类型
   factory-method一定是工厂里面的静态方法 
-->
    <bean id="helloWorldFactory" class="com.lanou.domain.HelloWorldFactory" factory-method="getInstance"></bean>

/**
     * 静态工厂
     * 在spring 内部,调用了HelloWorldFactory 内部的 getInstance 内部方法
     * 而该方法的内容,就是创建对象的过程,是由程序员来完成的
     * 这就是静态工厂
     * */
    @Test
    public  void testHelloWorldFactory(){
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloWorld helloWorld=(HelloWorld)context.getBean("helloWorldFactory");
        helloWorld.sayHello();
    }

3.2.1.4 实例工厂

public class HelloWorldFactory2 {
      public  HelloWorld getInstance(){
          return new HelloWorld();
      }
}
 <!--实例工厂
    工厂类创建对象 
    工厂类,实例方法,必须先创建工厂
    再创建user对象,用factory的实例方法   
-->
    <bean id="helloWorldFactory2" class="com.lanou.domain.HelloWorldFactory2">
    </bean>
    <!--factory-bean  指向实例工厂的bean-->
    <!--factory-method 实例工厂对象的方法-->
    <bean  id="helloWorld3" factory-bean="helloWorldFactory2" factory-method="getInstance">
    </bean>

/**
     * 实例工厂
     *   1.spring容器(beans)创建了一个实例工厂的bean
     *   2.该bean 调用了工厂方法的getInstance 方法产生对象
     * */
    @Test
    public void testHelloWorldFactory2(){
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloWorld helloWorld=(HelloWorld)context.getBean("helloWorld3");
        helloWorld.sayHello();
    }

3.2.2对象的 scope

简单说就是对象在spring容器(IOC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式。

目前,scope的取值有5种取值:
在Spring 2.0之前,有singleton和prototype两种;

在Spring 2.0之后,为支持web应用的ApplicationContext,增强另外三种:request,session和global session类型,它们只实用于web程序,通常是和XmlWebApplicationContext共同使用。

3.2.2.1 singleton(默认)

每个Spring IoC 容器中一个bean定义只有一个对象实例(共享).

此取值时表明容器中创建时只存在一个实例,所有引用此bean都是单一实例。此外,singleton类型的bean定义从容器启动到第一次被请求而实例化开始,只要容器不销毁或退出,该类型的bean的单一实例就会一直存活,典型单例模式,如同servlet在web容器中的生命周期。

3.2.2.2 prototype

允许bean可以被多次实例化(使用一次就创建一个实例) . Spring不能对一个prototype bean的整个生命周期负责. 无论lazy-init 的值是什么, 都在 context.getBean时才创建对象.

spring容器在进行输出prototype的bean对象时,会每次都重新生成一个新的对象给请求方,虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求方之后,容器就不在拥有当前对象的引用,请求方需要自己负责当前对象后继生命周期的管理工作,包括该对象的销毁。也就是说,容器每次返回请求方该对象的一个新的实例之后,就由这个对象“自生自灭”,最典型的体现就是spring与struts2进行整合时,要把action的scope改为prototype。

3.2.2.3 Request

再次说明 request,session和global session类型只实用于web程序,通常是和XmlWebApplicationContext共同使用,作用域仅在基于web的Spring ApplicationContext情形下有效。

request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前 HTTP request 内有效。当处理请求结束,request作用域的bean实例将被销毁。

3.2.2.4 Session

session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效。

3.2.2.5 Global session

在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。

3.2.3 初始化 bean 的时机

Spring 默认在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化的一部分,ApplicationContext 会自动创建并配置所有的singleton bean.
通常情况下这是件好事。因为这样在配置中有任何错误能立即发现。

lazy-init="true" OR "false"

Lazy-init 为false,spring容器将在启动的时候报错(比较好的一种方式)
Lazy-init 为true, spring容器将在调用该类的时候出错。
<bean id="per1" class="com.lanou.domain.Person"/>
<bean id="per2" class="com.lanou.domain.Person" lazy-init="true"/>

可以打断点查看无参构造函数的执行

@Test
public void testPerson_lazy_init_true(){
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Person person = (Person) context.getBean("per1");
    /* lazy-init="true"
    * 在 context.getBean("per2") 时才创建该对象
    * */
    Person person2 = (Person) context.getBean("per2");
}

如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:
<beans default-lazy-init="true“ ...>

3.2.4 init, destroy

Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。

public class Person {

    public void init(){
        System.out.println("初始化");
    }

    public void destroy(){
        System.out.println("销毁");
    }
}
<bean id="per1" class="com.lanou.domain.Person" init-method="init" destroy-method="destroy"/>

当 per1 被载入到Spring容器中时调用init-method方法。当 per1 从容器中删除时调用 destroy-method(scope = singleton有效)

/**
 * 在构造方法之后立即执行 init 方法,
 * 如果 spring 执行close方法, 在执行该方法前执行 destroy 方法
 */

@Test
public void testPerson_init_destroy() {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Person person = (Person) context.getBean("per1");
    ((ClassPathXmlApplicationContext) context).close(); //spring 容器关闭
}

3.3 别名

<bean id="car" name="BMCar" class="com.lanou.domain.Car"></bean>
    <!-- name的属性值和id对应-->
    <alias name="car" alias="QQ"/>
    <alias name="car" alias="劳斯莱斯"/>
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car1 = (Car) context.getBean("car");
Car car2 = (Car) context.getBean("QQ");
Car car3 = (Car) context.getBean("劳斯莱斯");
// 都是同一个对象
System.out.println(car1);
System.out.println(car2);
System.out.println(car3);

Spring4.3.8学习[二]
Spring4.3.8学习[三]
Spring4.3.8学习之 与 Struts2 整合[四]
Spring4.3.8学习之与Hibernate4 整合[五]
Spring4.3.8学习之S2SH 整合[六]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容