1. 什么是框架
框架指的是针对某一个(某一系列)共性问题的通用解决方案
2. 为什么要学习spring,spring能给我们带来什么
- 为什么要学习spring
- 为什么需要面向接口编程
- 耦合、依赖的概念
- IOC和DI的概念
3. spring的概念
-
广义的spring指的是spring的生态:spring,springMVC,springboot,spring cloud,spring security,spring data等
-
狭义的spring。指的就是spring framework本身。 它是其他spring框架的基础。很重要!
4. spring中的IOC容器
ApplicationContext是spring的IOC容器。是一个接口。
ApplicationContext的父接口,也就是顶层接口是:BeanFactory
平时我们常用的有:ClassPathXmlApplicationContext , AnnotationConfigApplicationContext
5. spring的快速入门
添加依赖
java
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<servlet.version>6.0.0</servlet.version>
<junit.version>5.10.1</junit.version>
<mysql.version>8.0.32</mysql.version>
<spring.version>6.0.11</spring.version>
<lombok.version>1.18.24</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
新建Person类
java
public class Person {
public void sayHello(){
System.out.println("大家好,肚子好饿!");
}
}
新建spring的IOC配置文件:applicationContext.xml , 在其中描述Person
xml
<bean id="p01" class="com.bottom.ioc.Person"/>
测试,从IOC容器中获取person实例对象
6. 获取bean的方式
Object getBean(id)
java
@Test
public void test01(){
System.out.println(beanFactory.getBean("p01"));
}
T getBean(Class)
java
@Test
public void test01(){
System.out.println(beanFactory.getBean(Person.class));
}
T getBean(id,Class)
java
@Test
public void test01(){
System.out.println(beanFactory.getBean("p01",Person.class));
}
注意点:
- 根据id获取,有可能获取不到,获取不到则报错 NoSuchBeanDefinitionException: No bean named 'p02' available
- 根据类型获取,有且唯一,则获取成功;否则报错 NoUniqueBeanDefinitionException:expected single matching bean but found 2: p01,p02 小结:
- 根据id获取,返回Object类型。没有则报错
- 根据class获取,直接返回对应的类型。如果没有或不唯一则报错。
- 同时根据id和class获取。
7. spring的IOC容器实质上也是通过反射技术去创建bean实例
- 创建Bean实例的方式一
8. 属性赋值
- setter赋值 spring通过反射技术调用对象中的setter方法,从而完成属性赋值
xml
<bean id="s01" class="com.bottom.ioc.Student">
<property name="sid" value="s001"/>
<property name="sname" value="鸠摩智"/>
<property name="age" value="30"/>
</bean>
- ref赋值
xml
<bean id="t01" class="com.bottom.ioc.Teacher">
<property name="tname" value="爱因斯坦"/>
<property name="book" ref="b01"/> <!-- reference:引用 -->
</bean>
- 内部bean赋值
xml
<bean id="t02" class="com.bottom.ioc.Teacher">
<property name="tname" value="爱迪生"/>
<property name="book">
<bean class="com.bottom.ioc.Book">
<property name="bookName" value="MySQL从删库到跑路"/>
<property name="price" value="98"/>
</bean>
</property>
</bean>
-
导入properties文件给属性赋值
两个注意点: ① properties文件中,等号两边不要有空格 ② properties文件中的key,一般是由多个单词组成,目的是为了避免和系统的某些属性名冲突,从而导致你获取到的是系统属性值
xml
<!-- 1.先引入properties文件 -->
<context:property-placeholder location="classpath:car.properties" file-encoding="UTF-8"/>
xml
<!-- 2.使用properties文件中的值给属性赋值 -->
<bean id="car01" class="com.bottom.ioc.Car">
<property name="cid" value="${cid}"/>
<property name="cname" value="${cname}"/>
<property name="price" value="${price}"/>
<property name="username" value="${username}"/>
</bean>
- 构造器注入
xml
<!-- Ambiguous:模棱两可的 -->
<bean id="tiger001" class="com.bottom.ioc.Tiger">
<constructor-arg value="3" index="1" type="java.lang.Integer" name="age"/>
<constructor-arg value="东北虎"/>
</bean>
- P名称空间
xml
<!-- 通过p名称空间给属性赋值 -->
<bean id="book002" class="com.bottom.ioc.Book" p:bookName="PHP是全世界最好的语言" p:price="96"/>
- 属性级联
xml
<!-- 级联属性赋值 -->
<bean id="book001" class="com.bottom.ioc.Book"/>
<bean id="tea001" class="com.bottom.ioc.Teacher">
<property name="tname" value="牛顿"/>
<property name="book" ref="book001"/>
<property name="book.bookName" value="21天精通C++"/>
<property name="book.price" value="97"/>
</bean>
- 数组或集合类型的属性
xml
<!-- 属性赋值,属性是:数组、List、Set、Map、Properties -->
<bean id="zoo" class="com.bottom.ioc.Zoo">
<property name="zooName" value="深圳动物园"/>
<property name="tigerArr">
<array>
<ref bean="tiger01"/>
<ref bean="tiger02"/>
<ref bean="tiger03"/>
</array>
</property>
<property name="tigerList">
<list>
<ref bean="tiger02"/>
<ref bean="tiger03"/>
</list>
</property>
<property name="tigerSet">
<set>
<ref bean="tiger04"/>
</set>
</property>
<property name="tigerMap">
<map>
<entry key="t001" value-ref="tiger01"/>
<entry key="t002" value-ref="tiger02"/>
<entry key="t003" value-ref="tiger03"/>
<entry key="t004" value-ref="tiger04"/>
</map>
</property>
<property name="properties">
<props>
<prop key="tiger001">东北虎</prop>
<prop key="tiger002">华南虎</prop>
</props>
</property>
</bean>
- 集合类型的bean对象
xml
<util:list id="tigerList">
<list>
<ref bean="tiger02"/>
<ref bean="tiger03"/>
</list>
</util:list>
9. 通过静态工厂方法创建bean实例
创建Bean实例的方式二
1.创建 Car类
java
@Data
public class Car {
private Integer cid ;
private String cname ;
private Integer price ;
private String username;
}
2.创建CarFactory
java
public class CarFactory {
//静态的工厂方法
public static Car getCarInstance(){
Car car = new Car();
car.setCid(99);
car.setCname("大众捷达");
car.setPrice(50);
return car ;
}
}
3.在xml注入bean信息
xml
<!-- car99这个对象需要通过CarFactory这个类的getCarInstance方法产生 -->
<bean id="car99" class="com.bottom.ioc.CarFactory" factory-method="getCarInstance"/>
4.在测试类测试
java
@Test
public void test10(){
System.out.println(beanFactory.getBean("car99"));
}
10. 通过工厂方法创建bean实例
创建Bean实例的方式三
1.创建book 类
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
private String bookName ;
private double price ;
}
2.创建 BookFactory
java
public class BookFactory {
public Book getBookInstance(){
Book book = new Book("Spring从入门到精通",101);
return book ;
}
}
3.在xml注入bean信息
xml
<!-- car99这个对象需要通过CarFactory这个类的getCarInstance方法产生 -->
<bean id="car99" class="com.bottom.ioc.CarFactory" factory-method="getCarInstance"/>
4.在测试类测试
java
@Test
public void test11(){
System.out.println(beanFactory.getBean("book99"));
}
11. scope的取值
-
singleton : 默认值,单例
-
prototype : 多例
12. bean的初始化方法和销毁方法(指定bean在初始化和销毁时分别调用的方法)
1.创建dog类
java
public class Dog {
public Dog(){
System.out.println("Dog无参构造方法被调用...");
}
public void dogInit(){
System.out.println("Dog正在初始化...");
}
public void dogDestroy(){
System.out.println("Dog正在销毁....");
}
}
2.在xml注入bean信息
xml
<bean id="dog" class="com.bottom.ioc.Dog" init-method="dogInit" destroy-method="dogDestroy"/>
3.在测试类测试
java
@Test
public void test02(){
beanFactory.getBean(Dog.class);
((ClassPathXmlApplicationContext)beanFactory).close();
}
13.通过FactoryBean机制创建Bean实例
创建Bean实例的方式四
1.创建cat类
java
@Data
public class Cat {
private String cname ;
private Integer age ;
}
2.创建CatFactoryBean
java
public class CatFactoryBean implements FactoryBean<Cat> {
@Override
public Cat getObject() throws Exception {
Cat cat = new Cat();
cat.setCname("tom");
cat.setAge(2);
return cat;
}
@Override
public Class<?> getObjectType() {
return Cat.class;
}
}
3.在xml注入bean信息
xml
<!-- 通过FactoryBean机制产生bean实例 -->
<bean id="cat01" class="com.bottom.ioc.CatFactoryBean"/>
4.在测试类测试
csharp
@Test
public void test03(){
System.out.println(beanFactory.getBean("cat01"));
}
14.bean的生命周期(重要)
- IOC容器中的bean实例默认是单例的;
- 单例的实例是在容器创建的时候就产生了;多例是在要使用时才会产生。
- BeanPostProcessor-Bean后置处理器 如果在bean实例初始化的前后有需要做的事情,我们可以使用后置处理器实现