[Spring][SpringFramework]#1_IoC

QuickStart

IoC容器实现步骤:

  • 在 pom.xml 中添加 Spring 依赖
  • 创建配置文件,可以自定义文件名 spring.xml
  • 在 spring.xml 中配置 bean 标签,IoC 容器通过加载 bean 标签来创建对象
  • 调用 API 获取 IoC 创建的对象
  1. 无参构造
<!-- 配置 student 对象 -->
<bean id="stu" class="com.southwind.entity.Student">
    <property name="id" value="1"></property>
    <property name="name" value="张三"></property>
    <property name="age" value="23"></property>
</bean>

<!-- 配置 student 对象 (包含特殊字符)-->
<bean id="stu" class="com.southwind.entity.Student">
   <property name="id" value="1"></property>
   <property name="name">
       <value><![CDATA[<张三>]]></value>
   </property>
   <property name="age" value="23"></property>
</bean>

Spring 通过调用每个属性的 setter 方法来完成属性的赋值,因此实体类必须有 setter 方法

//1.加载 spring.xml 配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//2.通过 id 值获取对象
Student stu = (Student) applicationContext.getBean("stu");
//Student stu = applicationContext.getBean(Student.class);
System.out.println(stu);
  1. 有参构造
<!-- 通过有参构造函数创建对象 -->
<bean id="stu3" class="com.hzit.entity.Student">
   <constructor-arg name="id" value="3"></constructor-arg>
   <constructor-arg name="name" value="小明"></constructor-arg>
   <constructor-arg name="age" value="22"></constructor-arg>
</bean>

<!-- 通过有参构造函数创建对象 -->
<bean id="stu3" class="com.hzit.entity.Student">
   <constructor-arg index="0" value="3"></constructor-arg>
   <constructor-arg index="1" value="小明"></constructor-arg>
   <constructor-arg index="2" value="22"></constructor-arg>
</bean>
  1. 对象之间有级联关系
public class Classes {
    private int id;
    private String name;
}
public class Student {
    private int id;
    private String name;
    private int age;
    private Classes classes;
}
<!-- 创建 classes 对象 -->
<bean id="classes" class="com.hzit.entity.Classes">
   <property name="id" value="1"></property>
   <property name="name" value="Java班"></property>
</bean>
<!-- 创建 stu 对象 -->
<bean id="stu" class="com.hzit.entity.Student">
   <property name="id" value="1"></property>
   <property name="name">
       <value><![CDATA[<张三>]]></value>
   </property>
   <property name="age" value="23"></property>
   <!-- 将 classes 对象赋给 stu 对象 -->
   <property name="classes" ref="classes"></property>
</bean>
  1. 集合属性的依赖注入
public class Classes {
    private int id;
    private String name;
    private List<Student> students;
}
<!-- 配置 classes 对象 -->
<bean id="classes" class="com.hzit.entity.Classes">
   <property name="id" value="1"></property>
   <property name="name" value="Java班"></property>
   <property name="students">
       <!-- 注入 student 对象 -->
       <list>
           <ref bean="stu"/>
           <ref bean="stu2"/>
       </list>
   </property>
</bean>

bean的scope

  • singleton,单例,表示通过 Spring 容器获取的该对象是唯一的;
  • prototype,原型,表示通过 Spring 容器获取的对象都是不同的;
  • request,请求,表示在一次 HTTP 请求内有效;
  • session,会话,表示在一个用户会话内有效。

Spring 的继承

Spring 的继承是在对象层面进行操作的,即两个 bean 来自同一个类,因此方法是一样的,不存在继承关系

<bean id="user" class="com.southwind.entity.User">
   <property name="id" value="1"></property>
   <property name="name" value="张三"></property>
   <property name="age" value="23"></property>
</bean>
<bean id="user2" class="com.southwind.entity.User" parent="user">
   <!-- 覆盖 name 属性 -->
   <property name="name" value="李四"></property>
</bean>
User user2 = (User) applicationContext.getBean("user2");
System.out.println(user2);

创建了两个 User 对象 user1 和 user2,并且 user2 继承了 user1 的所有属性。user2 在继承 user1 所有属性的基础之上,还可以对属性进行覆盖

Spring 的依赖

配置依赖关系后,被依赖的 bean 一定先创建,再创建依赖的 bean

<bean id="user" class="com.southwind.entity.User" depends-on="car">
   <property name="id" value="1"></property>
   <property name="name" value="张三"></property>
   <property name="age" value="23"></property>
</bean>
<bean id="car" class="com.southwind.entity.Car">
   <property name="id" value="1"></property>
   <property name="brand" value="宝马"></property>
</bean>
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
User user = (User) applicationContext.getBean("user");
Car car = (Car) applicationContext.getBean("car");

目前为止发现的bean构造顺序:1. singleton bean(根据xml中顺序,遇到deponds-on项先创建 2.prototype bean(根据java中顺序)

Spring 读取外部资源

# resources/jdbc.properties
driverName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/myTest?useUnicode=true&characterEncoding=UTF-8
user = root
pwd = root
       <!--xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context"-->

<!-- 导入外部的资源文件 -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 创建 C3P0 数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
   <property name="user" value="${user}"></property>
   <property name="password" value="${pwd}"></property>
   <property name="driverClass" value="${driverName}"></property>
   <property name="jdbcUrl" value="${url}"></property>
</bean>
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
DataSource ds = (DataSource) applicationContext.getBean("dataSource");
Connection conn = null;
try {
     conn = ds.getConnection();
} catch (SQLException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
}
System.out.println(conn);

p 命名空间

<!--xmlns:p="http://www.springframework.org/schema/p-->
<bean id="user" class="com.southwind.entity.User" p:id="1" p:name="张三" p:age="23" p:car-ref="car"></bean>
<bean id="car" class="com.southwind.entity.Car" p:id="1" p:brand="宝马"></bean>

IoC 通过工厂方法创建对象

静态工厂方法

public class StaticCarFactory {
    private static Map<Integer,Car> cars;
    static{
        cars = new HashMap<Integer,Car>();
        cars.put(1, new Car(1,"奥迪"));
        cars.put(2, new Car(2,"奥拓"));
    }
    public static Car getCar(int num){
        return cars.get(id);
    }
}
<!-- 配置静态工厂创建 car 对象 -->
<bean id="car1" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
   <constructor-arg value="1"></constructor-arg>
</bean>

实例工厂方法

public class InstanceCarFactory {
    private Map<Integer,Car> cars;
    public InstanceCarFactory() {
        cars = new HashMap<Integer,Car>();
        cars.put(1, new Car(1,"奥迪"));
        cars.put(2, new Car(2,"奥拓"));
    }
    public Car getCar(int num){
        return cars.get(num);
    }
}
<!-- 配置实例工厂对象 -->
<bean id="carFactory" class="com.southwind.entity.InstanceCarFactory"></bean>
<!-- 通过实例工厂对象创建 car 对象 -->
<bean id="car2" factory-bean="carFactory" factory-method="getCar">
    <constructor-arg value="2"></constructor-arg>
</bean> 

IoC 自动装载(autowire)

byName,通过属性名自动装载;

<bean id="person" class="com.southwind.entity.Person" autowire="byName"> 
   <property name="id" value="1"></property>
   <property name="name" value="张三"></property>
</bean>
<bean id="car" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
   <constructor-arg value="2"></constructor-arg>
</bean>

<!--创建 person 对象时,没有在 property 中配置 car 属性,因此 IoC 容器会自动进行装载,autowire="byName" 表示通过匹配属性名的方式去装载对应的 bean,Person 实体类中有 car 属性,因此就将 id="car" 的 bean 注入到 person 中。-->

byType,通过属性对应的数据类型自动装载

<bean id="person" class="com.southwind.entity.Person" autowire="byType"> 
    <property name="id" value="1"></property>
    <property name="name" value="张三"></property>
</bean>
<bean id="car" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
    <constructor-arg value="1"></constructor-arg>
</bean>

基于注解的开发

IoC 中可以给类添加的注解

  • @Controller
  • @Autowired
  • @Service
  • @Repository
发布了78 篇原创文章 · 获赞 0 · 访问量 1387

猜你喜欢

转载自blog.csdn.net/qq_30782921/article/details/103688496
今日推荐