Spring初识

Spring

简介

翻译:春天
意义:JavaEE开发者的春天

是一个一站式的分层结构 轻量级开发框架
目前最受欢迎的框架

特点

开源
轻量级:体积小 核心文件不到两兆
分层框架:用什么 拿什么 按需添加
一站式(对目前流行的框架支持非常高)
IOC
DI

就把他理解为对象的管家 帮我们管理项目中用到的对象
其实说白了 就是容器

优点

降低复杂性
松耦合
高性能
易测试 iunit
声明式事务

怎么用?

创建Spring
    1.下载jar包
    2.导入核心包 beans context expression core  logging(日志包)
    3.创建编写配置文件  
        创建对象交给Spring来管理
    4.创建ApplicationContext容器
    5.通过getBean来获取到对象 如果对象不为空 则Spring搭建成功
IOC
inverse of control 反转控制
说白了  就是把对象创建反转(交给)给Spring来管理
然后我们再从Spring中获取对象
之前 是我们自己创建对象 现在是问Spring拿对象
实现原理:通过反射 + 配置文件来达到
Class c = Class.forName("com.lanou.Person");
Object o = c.newIncetance();
context.put("person",o);
context.get("person");
DI技术
dependency  injection
依赖         注入
类A中需要B类提供的功能  称为A依赖B
例如:Service 依赖 DAO
UserService
UserDao dao = new UserDaoImplForJDBC();
UserDao dao = new UserDaoImplForHibernate();
使用Spring之后
UserDao dao = context.getBean("userDaoimpl");
不需要修改源代码就能实现组件的切换

注入:从外部把需要的对象放入 就叫注入
依赖注入的最终目的 就是提高程序的扩展性 尽可能不去修改源代码

注入属性的四种方式

方式一:set注入
set注入 在注入属性时 只要求该对象有set()/get()方法即可 无需有构造函数  在实现的时候通过property标签实现注入功能
不过在注入之前 是需要先获取那个类的对象 然后才可以对对象进行操作 获取对象的方式有三种
1.通过构造方法获取对象
2.通过静态工工厂获取对象
3.通过动态工厂获取对象
Person类
package com.lanou;

public class Person {
    private String username;
    private int age;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [username=" + username + ", age=" + age + "]";
    }

}
applicationContext.xml
<?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.xsd">
    <bean name="person1" class="com.lanou.Person"></bean>
</beans>
HelloSpring类
想要从容器中获取被管理的对象
第一步 创建容器 创建时需指定配置文件的地址
方法为: ClassPathXmlApplicationContext()参数为配置文件地址
可以理解为根据类路径的xml文件创建容器
参数:"classpath:applicationContext.xml"
如果在src目录下 classpath可以省略不写
第二步 从容器中获取bean对象


package com.lanou;

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

public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Person person = (Person)ac.getBean("person1");
        System.out.println(person);
    }
}

这里写图片描述

对applicationContext.xml稍作修改
这里体现了set方法的用处 直接用property对属性进行赋值 这里属性名一定要对应上
<bean name="person1" class="com.lanou.Person">
    <property name="username" value="张三"></property>
    <property name="age" value="14"></property>
</bean>

这里写图片描述

ref的使用
value属性用于 注入基本数据类型
ref属性用于 注入引用数据类型
创建Car类
package com.lanou;

public class Car {
    private String name,color;
    public Car() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Car(String name, String color) {
        super();
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Car [name=" + name + ", color=" + color + "]";
    }

}
修改person类
package com.lanou;

public class Person {
    private String username;
    private int age;
    private Car car;

    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    public Person() {
        super();
        System.out.println("我是无参构造方法");
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [username=" + username + ", age=" + age + ", car=" + car + "]";
    }

}
修改配置文件
<?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.xsd">
    其实bean 中不只name  class 这两个属性 还有method属性  当不写时 默认调用构造方法来创建对象
     name属性用来接收该对象 构造方法所创建出来的对象 class则需要指出是哪个类 因此需要全限定类名
    <bean name="person1" class="com.lanou.Person">
        <property name="username" value="张三"></property>
        <property name="age" value="14"></property>
        <property name="car" ref="car"></property>
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="红色"></property>
    </bean>
</beans>

这里写图片描述

第一种:通过构造方法
第一种为使用该类的无参构造方法  在没有有参构造方法的前提下 无论自己写不写无参构造方法都不重要 自己不写无参构造方法的话
系统会默认给你添加上无参构造方法  在<bean name="person1" class="com.lanou.Person" factory-method=""></bean> 
其中factory-method的方法对应的就是构造方法 默认规定 构造方法的时候 可以省略method不写
第二种:通过静态工厂
applicationContext.xml
到PersonFactory中调用getPerson的静态方法来获取对象
并放入容器中 如果使用默认的创建方式 Spring会到类中找到空参构造函数
如果指定了factory-method Spring就到类中找到指定的静态方法执行
而不是使用构造方法创建PersonFactory对象 而是使用里面的静态方法 
执行里面的静态方法  返回一个对象  用person2接收来接收所创建的对象

class指定类型 可以与bean的类型不一致 class代表的是可以取出对象的类 而不关心最终该对象来自于哪个类
比如下面的获取的person2对象 是属于Person类 而却是从personFactory工厂中获取的  当然personFactory
工厂中 调用了Person类来创建对象
<?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.xsd">
    <bean name="person2" class="com.lanou.PersonFactory" factory-method="getPerson">
        <property name="username" value="李四"></property>
        <property name="age" value="15"></property>
    </bean>
</beans>
HelloSpring
package com.lanou;

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

public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Person person2 = (Person)ac.getBean("person2");
        System.out.println(person2);
    }
}
Person
package com.lanou;

public class Person {
    private String username;
    private int age;
    private Car car;

    public Car getCar() {
        return car;
    }
    public Person(String username, int age, Car car) {
        super();
        this.username = username;
        this.age = age;
        this.car = car;
    }

    public void setCar(Car car) {
        this.car = car;
    }
    public Person() {
        super();
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [username=" + username + ", age=" + age + ", car=" + car + "]";
    }
}
PersonFactory.java
public class PersonFactory {
    public static Person getPerson() {
        // 静态工厂方式创建bean(当我们希望自己创建对象时 使用)
        return new Person();
    }
}

这里写图片描述

第三种:实例化工厂方法创建
PersonFactory.java
实例化工厂时 里面所用的方法没有使用static关键字 不是静态方法 调用此方法获取对象时 任然需要制定方法名
package com.lanou;
public class PersonFactory {
    public static Person getPerson() {
        // 静态工厂方式创建bean(当我们希望自己创建对象时 使用)
        return new Person();
    }
    public  Person getPerson2() {
        System.out.println("实例工厂方法");
        return new Person();
    }
}
PersonFactory.java
<?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.xsd">
    <!-- 使用实例化方法创建对象时 得知道方法在哪个类中 -->
    <bean class="com.lanou.PersonFactory" name="personF"></bean>
    <bean name="person3" class="com.lanou.PersonFactory" factory-method="getPerson2" factory-bean="personF" >
        <property name="username" value="赵六"></property>
    </bean>
</beans>
HelloSpring.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

        Person person3 = (Person)ac.getBean("person3");
        System.out.println(person3);
    }
}

这里写图片描述

方式二:构造函数注入属性
Car.java
package com.lanou;

public class Car {
    private String name,color;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Car [name=" + name + ", color=" + color + "]";
    }

}
Person.java
package com.lanou;

public class Person {
    private String username;
    private int age;
    private Car car;

    public Car getCar() {
        return car;
    }

    public Person(String username, int age, Car car) {
        super();
        this.username = username;
        this.age = age;
        this.car = car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    public Person() {
        super();
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [username=" + username + ", age=" + age + ", car=" + car + "]";
    }
}
applicationContext.xml
<?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.xsd">

    <bean name="person4" class="com.lanou.Person">
        <constructor-arg name="username" value="张三"></constructor-arg>
        <constructor-arg name="age" value="15"></constructor-arg>
        <constructor-arg name="car" ref="car"></constructor-arg>
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="绿色"></property>
    </bean>
</beans>
HelloSpring.java
package com.lanou;

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

public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

        Person person4 = (Person)ac.getBean("person4");
        System.out.println(person4);
    }
}
设置Car类对象的属性时 使用的是set方法赋值 设置Person类的对象属性的时候使用的是构造方法赋值 

这里写图片描述

对applicationContext.xml中内容稍作修改
<bean name="person4" class="com.lanou.Person">
    <constructor-arg name="username" value="张三"></constructor-arg>
    <constructor-arg name="car" ref="car"></constructor-arg>
    <constructor-arg name="age" value="15"></constructor-arg>
</bean>
换一下他们的位置 发现输出结果任然不变 说明这三行的顺序不影响输出结果

这里写图片描述

再对Person类进行修改
主要修改的是再填一个重载的构造方法 xml如上所示 不再做修改 发现虽然第二个构造方法与xml中属性设置的顺序匹配
但输出结果显示执行的是第一个构造方法
public Person(String username, int age, Car car) {
    super();
    System.out.println("我是构造方法一");
    this.username = username;
    this.age = age;
    this.car = car;
}
public Person(String username, Car car,int age) {
    super();
    System.out.println("我是构造方法二");
    this.username = username;
    this.age = age;
    this.car = car;
}

这里写图片描述

之后再对application.xml进行修改 添加属性index
<bean name="person4" class="com.lanou.Person">
    <constructor-arg name="username" value="张三"></constructor-arg>
    <constructor-arg name="car" ref="car" index="1"></constructor-arg>
    <constructor-arg name="age" value="15"></constructor-arg>
</bean>
<bean name="car" class="com.lanou.Car">
    <property name="name" value="法拉利"></property>
    <property name="color" value="绿色"></property>
</bean>

由结果可知 index指定参数放到哪一个位置 当多个构造参数类型相同 但是顺序不同时 可以指定使用哪个构造参数

这里写图片描述

对person类进行修改 对xml也进行修改
package com.lanou;

public class Person {
    private String username;
    private String age;
    private Car car;
    public Person(String username, Car car, String age) {
        super();
        System.out.println("我是构造方法一");
        this.username = username;
        this.age = age;
        this.car = car;
    }
    public Person(String username, Car car,int age) {
        super();
        System.out.println("我是构造方法二");
        this.username = username;
        this.age = age + "";
        this.car = car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    public Person() {
        super();
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [username=" + username + ", age=" + age + ", car=" + car + "]";
    }
}


<?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.xsd">
    <bean name="person4" class="com.lanou.Person">
        <constructor-arg name="username" value="张三"></constructor-arg>
        <constructor-arg name="car" ref="car"></constructor-arg>
        <constructor-arg name="age" value="15" type="int"></constructor-arg>
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="绿色"></property>
    </bean>
</beans>

这里写图片描述

对xml再进行修改
将int改为String
<bean name="person4" class="com.lanou.Person">
    <constructor-arg name="username" value="张三"></constructor-arg>
    <constructor-arg name="car" ref="car"></constructor-arg>
    <constructor-arg name="age" value="15" type="String"></constructor-arg>
</bean>

这里写图片描述

type 通过指定参数的类型才确定使用哪个构造参数 适用于当多个构造方法参数顺序相同 但是类型不同时使用
PersonFactory.java
<?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.xsd"
    xmlns:p="http://www.springframework.org/schema/p">
    <bean name="pserson5" class="com.lanou.Person" p:username="老王" p:age="15" p:car-ref="car">
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="绿色"></property>
    </bean>
</beans>
HelloSpring.java
public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");     
        Person pserson5 = (Person)ac.getBean("pserson5");
        System.out.println(pserson5);
    }
}

这里写图片描述

SpEL注入
SpEL Spring的表达式语言 能够实现一些简单逻辑
与Jsp的EL一个性质
applicationContext.xml
<?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.xsd">
    <bean name="person1" class="com.lanou.Person">
        <property name="username" value="张飞"></property>
    </bean>
    <bean name="person2" class="com.lanou.Person">
        <property name="age" value="12"></property>
    </bean>
    <bean name="person3" class="com.lanou.Person">
        <property name="username" value="#{person1.username}"></property>
        <property name="age" value="#{person2.age}"></property>
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="绿色"></property>
    </bean>
</beans>
HelloSpring.java

public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");     
        Person person3 = (Person)ac.getBean("person3");
        System.out.println(person3);
    }
}

这里写图片描述

打印所创建的对象的地址
applicationContext.xml
<?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.xsd">
    <bean name="person3" scope="prototype" class="com.lanou.Person">
        <property name="username" value="曹操"></property>
        <property name="age" value="18"></property>
        <property name="car" ref="car"></property>
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="绿色"></property>
    </bean>
</beans>
HelloSpring.java
public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");     
         System.out.println(ac.getBean("person3").hashCode());
         System.out.println(ac.getBean("person3").hashCode());
         System.out.println(ac.getBean("person3").hashCode());
    }
}

这里写图片描述

applicationContext.xml
<?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.xsd">
    <bean name="person3" scope="singleton" class="com.lanou.Person">
        <property name="username" value="曹操"></property>
        <property name="age" value="18"></property>
        <property name="car" ref="car"></property>
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="绿色"></property>
    </bean>
</beans>

这里写图片描述

ApplicationContext 的两个实现类

ClassPathXMLApplicationContext 用于加载class路径下的配置文件
FileSystemXMLApplicationContext 加载系统路径下的配置文件
测试FileSystemXMLApplicationContext
注意:绝对路径前要加file: 否则会显示找不到这个文件
public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac1 = new FileSystemXmlApplicationContext("file:/Users/lanou/javaweb/SpringDay04/src/applicationContext.xml");
        System.out.println(ac1.getBean("person3"));
    }
}

这里写图片描述

复杂类型的注入

array 使用array子标签
      例如:<array>
            <value>123</value>
            <value>456</value>
              </array>

list 使用list子标签 同array
map 使用entry子标签
    例如<map>
            <entry key="xx" value=""></entry>
            <entry key-ref="引用类型" value=""></entry>
        </map>
properties 使用props子标签
    例如:<props>
            <prop key="xx>value</prop>
        </props>
<?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.xsd">
    <bean id="cBean" class="com.lanou.CollectionBean">
        <property name="array">
            <array>
                <value>张三</value>
                <value>李四</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>list1</value>
                <value>list2</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="map集合1" value="15"></entry>
                <entry key-ref="car" value="15"></entry>
                <entry key="15" value="car"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="user">root</prop>
                <prop key="password">admin</prop>
            </props>
        </property>
    </bean>
    <bean name="car" class="com.lanou.Car">
        <property name="name" value="法拉利"></property>
        <property name="color" value="红色"></property>
    </bean>
</beans>
public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new FileSystemXmlApplicationContext("file:/Users/lanou/javaweb/SpringDay04/src/applicationContext.xml");
        System.out.println(ac.getBean("cBean"));
    }
}
结果
CollectionBean [array=[张三, 李四], list=[list1, list2], map={map集合1=15, Car
[name=法拉利, color=红色]=15, 15=car}, properties={user=root, password=admin}]

配置文件模块化

当一个配置文件内容太多时 可以将其按照功能模块划分
1.在创建容器时 传入多个字符串对象(配置文件名)
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml","text.xml");
2.在配置文件中使用import标签导入    
<import resource="classpath:applicationContext.xml"/>

Spring

Spring作为框架 当然不应该每次请求都创建一次新的
我们Spring能够与项目的启动一并启动 跟随项目的停止一并销毁
    实现步骤
    1.在web.xml中配置监听器 使得项目启动时 Spring也能够一起启动
    org.springframework.web.context.ContextLoaderListener 
    当监听到应用启动时会创建Spring容器 并且放到ApplicationContext中
    2.WebApplicationContextUtils 工具用来从WEBApplication中取出Spring容器

<!-- 配置监听器 启动Spring -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class>
</listener>
<!-- 告诉Spring去那里找配置文件 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

两种容器

XMLBeanFactory
在car类中  添加无参构造方法
public class Car {
    private String name,color;

    public Car() {
        System.out.println("我是无参构造方法");
    }
}
此时执行main函数 无参构造方法中并没有输出数据 说明还没有创建对象
public static void main(String[] args) {
    Resource resource = new FileSystemResource("/Users/lanou/javaweb/SpringDay04/src/applicationContext.xml");
    BeanFactory factory = new XmlBeanFactory(resource);
}

在main函数中添加一句获取对象的语句 需要全路径 即
public static void main(String[] args) {
    Resource resource = new FileSystemResource("/Users/lanou/javaweb/SpringDay04/src/applicationContext.xml");
    BeanFactory factory = new XmlBeanFactory(resource);
}
System.out.println(factory.getBean("car"));
此时构造方法中的语句被输出 说明对象被创建
总结:BeanFactory工厂 在加载配置文件时 是不会实例化对象的 只有在获取对象时 才会实例化对象
ApplicationContext
当main函数中只有这一句的时候 执行main函数 Car类中的构造方法就已经执行了 输出了"我是无参构造方法"
public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}
说明在加载配置文件的时候 配置文件中的类就已经被加载(创建)了 而创建对象必定经过构造函数的

此功能的前提:scope="singleton"
只有在单例情况下 才能提前创建对象 因为在多例的情况下 根本不知道你需要多少个对象 所有也就无法提前给你创建好对象
测试其是单例 修改main函数为:
public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        ac.getBean("car");
        ac.getBean("car");
        ac.getBean("car");
    }
}
结果只输出一句"我是无参构造方法" 说明对象只被创建了一次
修改配置文件 将scope="singleton"改为scope="prototype"
<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.xsd">
    <bean name="car" class="com.lanou.Car" scope="prototype">
        <property name="name" value="法拉利"></property>
        <property name="color" value="红色"></property>
    </bean>
</beans>

public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}
此时Car中的构造函数并没有输出 说明虽然是ApplicationContext容器 但是在加载配置文件时 并没有创建对象 因为scope的属性是多例
修改main函数 为其添加获取对象的方法
public class HelloSpring {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        ac.getBean("car");
        ac.getBean("car");
        ac.getBean("car");
        System.out.println(factory.getBean("car"));
    }
}
结果打印了三句"我是无参构造方法"
init-method     对象创建完了立即执行
destroy-method  对象销毁前执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值