写在前面
谈谈我对spring的理解,大家一起学习。
Spring 框架文档官方链接
Spring Framework 的控制反转 (IoC) 容器
IoC 也称为依赖注入 (DI)。这是一个过程,其中对象仅通过构造函数参数、工厂方法的参数或在对象实例被构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖项(即,它们使用的其他对象) . 然后容器在创建 bean 时注入这些依赖项。这个过程基本上是 bean 本身的逆过程(因此得名,控制反转),通过使用类的直接构造或诸如服务定位器模式之类的机制来控制其依赖项的实例化或位置 。
我们通过idea(maven)来导入spring依赖
pom.xml文件
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.9</version>
</dependency>
里面的包都可以通过点这里导入,lombok是我们创建Class时可以使用的工具(蛮好用的,推荐)
ApplicationContext
在org.springframework.beans
和org.springframework.context
包是Spring框架的IoC容器的基础。该 BeanFactory 接口提供了一种能够管理任何类型对象的高级配置机制。 ApplicationContext 是 的子接口BeanFactory
。
在 Spring 中,构成应用程序主干并由 Spring IoC 容器管理的对象称为 bean。bean 是由 Spring IoC 容器实例化、组装和管理的对象。否则,bean 只是应用程序中众多对象之一。Bean 以及它们之间的依赖关系反映在容器使用的配置元数据中。
1、容器概述
该org.springframework.context.ApplicationContext
接口代表 Spring IoC 容器,负责实例化、配置和组装 bean。容器通过读取配置元数据来获取有关要实例化、配置和组装哪些对象的指令。配置元数据以 XML、Java 注释或 Java 代码表示。它可以让您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。
创建ClassPathXmlApplicationContext 或的实例 FileSystemXmlApplicationContext
1.1基于 XML 的配置元数据的基本结构
<bean id="user" class="zhou.com.pojo.User"></bean>
该id
属性是一个字符串,用于标识单个 bean 定义。
该class
属性定义 bean 的类型并使用完全限定的类名。
类User
lombok工具包中,帮我们完成了set,get,有参,无参,toString方法的书写
package zhou.com.pojo;
import lombok.*;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private String userName;
private String passWord;
private Role role;
}
测试
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
User user= (User) context.getBean("user");
System.out.println(user);
结果
可以看到,我们不需要在new对象了,这一系列都交给spring帮我们管理了
下面是一系列实例化对象xml文件的配置
1.2property(set方法注入)以及p:
<bean id="user" class="zhou.com.pojo.User">
<property name="passWord" value="psw"/>
<property name="userName" value="usm"/>
</bean>
name 属性名;value值
简写
<bean id="user" class="zhou.com.pojo.User" p:passWord="wsd" p:userName="usn"/>
p:的使用,头部需要声明
xmlns:p="http://www.springframework.org/schema/p"
1.3ref(DL依赖注入)
通过内部bean名字对类的依赖项实例化
<bean id="user" class="zhou.com.pojo.User">
<property ref="role" name="role"/>
</bean>
<bean id="role" class="zhou.com.pojo.Role" p:uid="3"/>
结果
1.4constructor-arg(构造方法注入)
<bean id="user" class="zhou.com.pojo.User">
<constructor-arg value="3" name="passWord"/>
<constructor-arg value="3" name="userName"/>
<constructor-arg name="role" ref="role"/>
</bean>
<bean id="role" class="zhou.com.pojo.Role" p:uid="3"/>
结果
1.5集合属性注入
<bean id="collectionTest" class="zhou.com.pojo.CollectionTest">
<constructor-arg name="strings">
<array>
<value>string1</value>
<value>string2</value>
</array>
</constructor-arg>
<constructor-arg name="list">
<list>
<value>list1</value>
<value>list1</value>
</list>
</constructor-arg>
<constructor-arg name="set">
<set>
<value>set</value>
<value>set1</value>
</set>
</constructor-arg>
<constructor-arg name="map">
<map>
<entry key="mapKey" value="mapValue"/>
<entry key="mapKey1" value="mapValue1"/>
</map>
</constructor-arg>
</bean>
结果
2bean生命周期
2.1init-method(初始化)和destroy-method(销毁)
测试类
public class L {
private String name;
public L(){
System.out.println("无参方法调用");
}
public void setName(String name) {
this.name = name;
System.out.println("set方法调用");
}
public void init(){
System.out.println("init方法调用");
}
public void destroy(){
System.out.println("destroy方法调用");
}
}
配置
<bean id="l" class="zhou.com.pojo.L" init-method="init" destroy-method="destroy"/>
init-method和destroy-method中的方法自己定义
测试
System.out.println("---配置文件加载---");
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("---获取bean---");
L l=context.getBean(L.class);
System.out.println("---清除资源---");
context.close();
结果
可以看到我们配置文件加载,我们容器中的对象调用各自的构造方法或者set方法创建,之后初始化方法被调用,然后我们通过getbean方法获取到容器中的对应对象,在之后我们调用close方法对我们的容器资源进行释放,此时销毁的方法被调用
为了更直观的感受,我们引入BeanPostProcessor
public class BeanL implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName+":"+bean+"前");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName+":"+bean+"后");
return null;
}
}
里面的方法是实现接口以后重写的,可以自己定义
xml文件配置
<bean id="beanL" class="zhou.com.pojo.BeanL"/>
在看一眼我们之前都配了什么
<bean id="beanL" class="zhou.com.pojo.BeanL"/>
<bean id="l" class="zhou.com.pojo.L" init-method="init" destroy-method="destroy"/>
<bean id="user" class="zhou.com.pojo.User">
<constructor-arg value="3" name="passWord"/>
<constructor-arg value="3" name="userName"/>
<constructor-arg name="role" ref="role"/>
</bean>
<bean id="role" class="zhou.com.pojo.Role" p:uid="3"/>
<bean id="collectionTest" class="zhou.com.pojo.CollectionTest">
<constructor-arg name="strings">
<array>
<value>string1</value>
<value>string2</value>
</array>
</constructor-arg>
<constructor-arg name="list">
<list>
<value>list1</value>
<value>list1</value>
</list>
</constructor-arg>
<constructor-arg name="set">
<set>
<value>set</value>
<value>set1</value>
</set>
</constructor-arg>
<constructor-arg name="map">
<map>
<entry key="mapKey" value="mapValue"/>
<entry key="mapKey1" value="mapValue1"/>
</map>
</constructor-arg>
</bean>
执行
System.out.println("---配置文件加载---");
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("---获取bean---");
L l=context.getBean(L.class);
System.out.println("---清除资源---");
context.close();
结果
可以看到在我们获取bean之前,加载配置文件之后对我们配置文件中的每个对象进行了加载,即每一个配置文件对应一个spring的容器,容器中承载着我们的对象资源。
写在最后
spring的内容本身就比较多,虽然说也是比较简单的框架了,但是还是要认真学习,如果文中有不当的地方,欢迎指正