Spring-01

1.Spring简介

  1. Spring是一个开源框架,它由[Rod Johnson]([https://baike.baidu.com/item/Rod](https://baike.baidu.com/item/Rod) Johnson)创建。它是为了解决企业应用开发的复杂性而创建的。
  2. 目前是JavaEE开发的灵魂框架。他可以简化JavaEE开发,可以非常方便整合其他框架,无侵入的进行功能增强。
  3. Spring的核心就是 控制反转(IoC)和面向切面(AOP)

2.IOC控制反转

2.1 概念

  1. 控制反转,之前对象的控制权在类手上,现在反转后到了Spring手上。

2.2 入门案例

①导入依赖

导入SpringIOC相关依赖

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-context</artifactId>
  4. <version>5.1.9.RELEASE</version>
  5. </dependency>

②编写配置文件

在resources目录下创建applicationContext.xml文件,文件名可以任意取。但是建议叫applicationContext。

内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--
  6. classs:配置类的全类名
  7. id:配置一个唯一标识
  8. -->
  9. <bean class="com.sangeng.dao.impl.StudentDaoImpl" id="studentDao" >
  10. </bean>
  11. </beans>

③创建容器从容器中获取对象并测试

  1. public static void main(String[] args) {
  2. // 1.获取StudentDaoImpl对象
  3. //创建Spring容器,指定要读取的配置文件路径
  4. ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
  5. //从容器中获取对象
  6. StudentDao studentDao = (StudentDao) app.getBean("studentDao");
  7. //调用对象的方法进行测试
  8. System.out.println(studentDao.getStudentById(1));
  9. }

2.3 Bean的常用属性配置

2.3.1 id

  1. bean的唯一标识,同一个Spring容器中不允许重复

2.3.2 class

  1. 全类名,用于反射创建对象

2.3.3 scope

  1. scope主要有两个值:singletonprototype
  2. 如果设置为singleton则一个容器中只会有这个一个bean对象。默认容器创建的时候就会创建该对象。
  3. 如果设置为prototype则一个容器中会有多个该bean对象。每次调用getBean方法获取时都会创建一个新对象。

3.DI依赖注入

  1. 依赖注入可以理解成IoC的一种应用场景,反转的是对象间依赖关系维护权。

3.1 set方法注入

在要注入属性的bean标签中进行配置。前提是该类有提供属性对应的set方法。

  1. package com.sangeng.domain;
  2. public class Student {
  3. private String name;
  4. private int id;
  5. private int age;
  6. private Dog dog;
  7. public Dog getDog() {
  8. return dog;
  9. }
  10. public void setDog(Dog dog) {
  11. this.dog = dog;
  12. }
  13. @Override
  14. public String toString() {
  15. return "Student{" +
  16. "name='" + name + '\'' +
  17. ", id=" + id +
  18. ", age=" + age +
  19. '}';
  20. }
  21. public Student() {
  22. }
  23. public Student(String name, int id, int age) {
  24. this.name = name;
  25. this.id = id;
  26. this.age = age;
  27. }
  28. public String getName() {
  29. return name;
  30. }
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34. public int getId() {
  35. return id;
  36. }
  37. public void setId(int id) {
  38. this.id = id;
  39. }
  40. public int getAge() {
  41. return age;
  42. }
  43. public void setAge(int age) {
  44. this.age = age;
  45. }
  46. }
  1. <bean class="com.sangeng.domain.Dog" id="dog">
  2. <property name="name" value="小白"></property>
  3. <property name="age" value="6"></property>
  4. </bean>
  5. <bean class="com.sangeng.domain.Student" id="student" >
  6. <!--
  7. name属性用来指定要设置哪个属性
  8. value属性用来设置要设置的值
  9. ref属性用来给引用类型的属性设置值,可以写上Spring容器中bean的id
  10. -->
  11. <property name="name" value="东南枝"></property>
  12. <property name="age" value="20"></property>
  13. <property name="id" value="1"></property>
  14. <property name="dog" ref="dog"></property>
  15. </bean>

3.2 有参构造注入

在要注入属性的bean标签中进行配置。前提是该类有提供对应的有参构造。

  1. public class Student {
  2. private String name;
  3. private int id;
  4. private int age;
  5. private Dog dog;
  6. public Student(String name, int id, int age, Dog dog) {
  7. this.name = name;
  8. this.id = id;
  9. this.age = age;
  10. this.dog = dog;
  11. }
  12. //.....省略其他
  13. }
  1. <!--使用有参构造进行注入-->
  2. <bean class="com.sangeng.domain.Student" id="student2" >
  3. <constructor-arg name="name" value="自挂东南枝"></constructor-arg>
  4. <constructor-arg name="age" value="20"></constructor-arg>
  5. <constructor-arg name="id" value="30"></constructor-arg>
  6. <constructor-arg name="dog" ref="dog"></constructor-arg>
  7. </bean>

3.3 复杂类型属性注入

实体类如下:

  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class User {
  5. private int age;
  6. private String name;
  7. private Phone phone;
  8. private List<String> list;
  9. private List<Phone> phones;
  10. private Set<String> set;
  11. private Map<String, Phone> map;
  12. private int[] arr;
  13. private Properties properties;
  14. }
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class Phone {
  5. private double price;
  6. private String name;
  7. private String password;
  8. private String path;
  9. }

配置如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <bean class="com.sangeng.domain.Phone" id="phone">
  6. <property name="price" value="3999"></property>
  7. <property name="name" value="黑米"></property>
  8. <property name="password" value="123"></property>
  9. <property name="path" value="qqqq"></property>
  10. </bean>
  11. <bean class="com.sangeng.domain.User" id="user">
  12. <property name="age" value="10"></property>
  13. <property name="name" value="大队长"></property>
  14. <property name="phone" ref="phone"></property>
  15. <property name="list">
  16. <list>
  17. <value>三更</value>
  18. <value>西施</value>
  19. </list>
  20. </property>
  21. <property name="phones">
  22. <list>
  23. <ref bean="phone"></ref>
  24. </list>
  25. </property>
  26. <property name="set">
  27. <set>
  28. <value>setEle1</value>
  29. <value>setEle2</value>
  30. </set>
  31. </property>
  32. <property name="map">
  33. <map>
  34. <entry key="k1" value-ref="phone"></entry>
  35. <entry key="k2" value-ref="phone"></entry>
  36. </map>
  37. </property>
  38. <property name="arr">
  39. <array>
  40. <value>10</value>
  41. <value>11</value>
  42. </array>
  43. </property>
  44. <property name="properties">
  45. <props>
  46. <prop key="k1">v1</prop>
  47. <prop key="k2">v2</prop>
  48. </props>
  49. </property>
  50. </bean>
  51. </beans>

4.Lombok

①导入依赖

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <version>1.18.16</version>
  5. </dependency>

②增加注解

  1. @Data //根据属性生成set,get方法
  2. @NoArgsConstructor //生成空参构造
  3. @AllArgsConstructor //生成全参构造
  4. public class Phone {
  5. private double price;
  6. private String name;
  7. private String password;
  8. private String path;
  9. }

5.SPEL

  1. 我们可以再配置文件中使用SPEL表达式。写法如下:
  1. <property name="age" value="#{20}"/>
  2. <property name="car" value="#{car}"/>
  1. 注意:SPEL需要写到value属性中,不能写到ref属性。

6.配置文件

6.1 读取properties文件

  1. 我们可以让Spring读取properties文件中的key/value,然后使用其中的值。

①设置读取properties

在Spring配置文件中加入如下标签:指定要读取的文件的路径。

  1. <context:property-placeholder location="classpath:filename.properties">

其中的classpath表示类加载路径下。

我们也会用到如下写法:classpath:**.properties 其中的 表示文件名任意。

注意:context命名空间的引入是否正确

②使用配置文件中的值

在我们需要使用的时候可以使用${key}来表示具体的值。注意要再value属性中使用才可以。例如:

  1. <property name="propertyName" value="${key}"/>

6.2 引入Spring配置文件

  1. 我们可以在主的配置文件中通过import标签的resource属性,引入其他的xml配置文件
  1. <import resource="classpath:applicationContext-book.xml"/>

7. 低频知识点

7.1 bean的配置

7.1.1 name属性

  1. 我们可以用name属性来给bean取名。例如:
  1. <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource" name="dataSource2,dataSource3">
  2. <property name="driverClassName" value="${jdbc.driver}"></property>
  3. <property name="url" value="${jdbc.url}"></property>
  4. <property name="username" value="${jdbc.username}"></property>
  5. <property name="password" value="${jdbc.password}"></property>
  6. </bean>
  1. 获取的时候就可以使用这个名字来获取了
  1. public static void main(String[] args) {
  2. ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
  3. DruidDataSource dataSource = (DruidDataSource) app.getBean("dataSource3");
  4. System.out.println(dataSource);
  5. }

7.1.2 lazy-init

  1. 可以控制bean的创建时间,如果设置为true就是在第一次获取该对象的时候才去创建。
  1. <bean class="com.alibaba.druid.pool.DruidDataSource" lazy-init="true" id="dataSource" name="dataSource2,dataSource3">
  2. <property name="driverClassName" value="${jdbc.driver}"></property>
  3. <property name="url" value="${jdbc.url}"></property>
  4. <property name="username" value="${jdbc.username}"></property>
  5. <property name="password" value="${jdbc.password}"></property>
  6. </bean>

7.1.3 init-method

  1. 可以用来设置初始化方法,设置完后容器创建完对象就会自动帮我们调用对应的方法。
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class Student {
  5. private String name;
  6. private int id;
  7. private int age;
  8. //初始化方法
  9. public void init(){
  10. System.out.println("对学生对象进行初始化操作");
  11. }
  12. }
  1. <bean class="com.sangeng.domain.Student" id="student" init-method="init"></bean>

注意:配置的初始化方法只能是空参的。

7.1.4 destroy-method

  1. 可以用来设置销毁之前调用的方法,设置完后容器销毁对象前就会自动帮我们调用对应的方法。
  1. <bean class="com.sangeng.domain.Student" id="student" destroy-method="close"></bean>
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class Student {
  5. private String name;
  6. private int id;
  7. private int age;
  8. public void init(){
  9. System.out.println("对学生对象进行初始化操作");
  10. }
  11. public void close(){
  12. System.out.println("对象销毁之前调用,用于释放资源");
  13. }
  14. }

注意:配置的方法只能是空参的。

7.1.5 factory-bean&factory-method

  1. 当我们需要让Spring容器使用工厂类来创建对象放入Spring容器的时候可以使用factory-beanfactory-method属性。

7.1.5.1 配置实例工厂创建对象

配置文件中进行配置

  1. <!--创建实例工厂-->
  2. <bean class="com.sangeng.factory.CarFactory" id="carFactory"></bean>
  3. <!--使用实例工厂创建Car放入容器-->
  4. <!--factory-bean 用来指定使用哪个工厂对象-->
  5. <!--factory-method 用来指定使用哪个工厂方法-->
  6. <bean factory-bean="carFactory" factory-method="getCar" id="car"></bean>

创建容器获取对象测试

  1. ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
  2. //获取car对象
  3. Car c = (Car) app.getBean("car");
  4. System.out.println(c);

7.1.5.2 配置静态工厂创建对象

配置文件中进行配置

  1. <!--使用静态工厂创建Car放入容器-->
  2. <bean class="com.sangeng.factory.CarStaticFactory" factory-method="getCar" id="car2"></bean>

创建容器获取对象测试

  1. ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
  2. //获取car对象
  3. Car c = (Car) app.getBean("car2");
  4. System.out.println(c);