Spring 框架
代码参考:git@github.com:chendingwu/SpringExample.git
- Spring是分层的JavaSE/JavaEE应用full-stack轻量级开源框架
IOC
- IOC(Iversion Of Control) 控制反转,Spring反向控制应用程序所需要使用的外部资源
- Spring控制的资源全部放置在Spring容器中,该容器称为IOC容器
bean
-
bean标签作用:定义spring中的资源,受此标签定义的资源将受到spring的控制
-
格式:
<beans>
<bean/>
</beans>
基本属性
<bean id="beanId" name="beanName1,beanName2,..." class="className" />
id:bean的名称,通过id获取bean
class:bean的类型
name:bean的名称,可以通过name值获取bean,用于多人配合时给bean起别名
bean属性scope
- scope:定义bean的作用范围
- 格式:
<bean scope="singleton" />
singleton: 设定创建出的对象保存在spring容器中,是一个单例的对象
prototype:设定创建出的对象保存在spring容器中,是一个非单例的对象
request,session,application,websocket:设定创建出的对象放置在web容器对应的位置
bean的生命周期
- init-method,destroy-method:定义bean对象在初始化或销毁完成后的工作
- 格式:
<bean init-method="init" destroy-method="destroy" />
注意:
- 当scope=“singleton”时,spring容器中有且仅有一个对象,init方法在创建容器时仅执行一次
- 当scope=“prototype”时,spring容器要创建同一类型的多个对象,init方法在每个对象创建时执行一次
- 当scope=“singleton”时,关闭容器会导致bean实例的销毁,嗲用destroy方法一次
- 当scope=“prototype”时,对象的销毁有垃圾回收机制gc()控制,destroy方法将不会被执行
bean对象的创建方式
- factory-bean:定义bean对象的创建方式,使用静态工厂的形式创建bean
- 格式:
<bean class="FactoryClassName" factory-method="factoryMethodName" />
注意:class属性必须配置成静态工厂类名
- factory-bean,factory-method:定义bean对象的创建方式,使用实例工厂的形式创建bean
- 格式:
<bean factory-bean="factoryBeanId" factory-method="factoryMethodName" />
注意:
- 使用实例工厂创建bean首先需要将实例工厂配置bean,交由spring进行管理
- factory-bean是实例工厂的beanId
DI
- DI(Dependency Injection)依赖注入,应用程序运行依赖的资源有spring为其提供,资源进入到应用程序的凡是称为注入
set注入
- property:使用set方法的形式为bean提供资源
- 格式:
<bean>
<property/>
</bean>
基本属性
<property name="propertyName" value="propertyValue" ref="beanId" />
name:对应bean中的属性名,要求该属性必须提供可访问的set方法,(严格规范为此名称是set方法对应的名称)
value:设定非引用类型属性对应的值,不能与ref同时使用
ref:设定引用类型属性对应的bean的id,不能与value同时使用
注意:一个bean可以有多个property标签
构造器注入
- constructor-arg:使用构造方法的形式为bean提供资源
- 格式:
<bean>
<constructor-arg />
</bean>
基本属性
<constructor-arg name="argsName" value="argsValue"/>
name:对应bean中的构造方法所携带的参数名
value:设定非引用类型构造方法参数对应的值,不能与ref同时存在
注意:一个bean可以有多个 constructor-arg 标签
其它属性
<constructor-arg index="arg-index" type="arg-type" ref="beanId"/>
ref:设定引用类型构造方法参数对应的bean的id,不能与value同时使用
type:设定构造方法参数的类型,用于按类型匹配参数或进行类型校验
index:设定构造方法参数的位置,用于按位置匹配参数,参数index值从0开始计数
集合类型数据注入
- array,list,set,map,props:注入集合数据类型属性
list
<property name="arrayList"><!--注入list集合数据-->
<list>
<value>小明</value>
<value>夏利</value>
<ref bean="user"/>
<bean class="cn.cdw.pojo.User"/>
</list>
</property>
properties
<property name="properties"><!--注入properties数据-->
<props>
<prop key="name">小明</prop>
<prop key="password">123456</prop>
</props>
</property>
数组
<property name="arr"> <!--注入数组数据-->
<array>
<value>100</value>
<value>200</value>
<value>300</value>
<ref bean="user"/>
<bean class="cn.cdw.pojo.User"/>
</array>
</property>
set
<property name="hashSet"> <!--注入set集合数据-->
<set>
<value>小明</value>
<value>小李</value>
<ref bean="user"/>
<bean class="cn.cdw.pojo.User"/>
</set>
</property>
map
<property name="hashMap"> <!--注入map集合数据-->
<map>
<entry key="name" value="小明"/>
<entry key="age" value="12"/>
<entry key="user1">
<ref bean="user"/>
</entry>
<entry key="user2">
<bean class="cn.cdw.pojo.User"/>
</entry>
</map>
</property>
使用p命名空间简化配置
-
p:prppertyName,p:propertyName-ref:为bean注入属性值
-
格式:
<bean p:propertyName="propertyValue" p:propertyName-ref="beanId" />
注意:使用p命令空间需要开启spring对p命令空间的支持,在beans标签中添加对应空间支持(可以去官方文档查看)
SpEL
- Spring提供了对EL表达式的支持,统一属性注入格式,为bean注入属性值
- 格式:
<property value="EL"/>
注意 : 所有属性值不区分是否引用类型,统一使用value赋值
类型 | 示例 |
---|---|
常量 | #{10} ,#{10.1} , #{“cdw”} |
引用bean | #{beanId} |
引用bean属性 | #{beanId.propertyName} |
运算符支持 | #{1 eq 1 == 5 ge 3} |
正则表达式支持 | #{user.name matches ‘[a-z]{6}’} |
集合支持 | #{likes[3]} |
properties文件
-
Spring提供了读取外部properties文件的机制,使用读取到的数据为bean的属性赋值,需要开启context命名空间支持。
-
加载指定的properties文件
<context:property-placeholder location="classpath:fileName.properties" />
- 使用加载的数据
<property name="propertyName" value="${propertiesName}" />
注意:
- 如果需要加载所有的properties文件,可以使用 *.properties表示加载所有的properties文件
- 读取数据使用${propertiesName}格式进行启动propertiesName指定properties文件中的属性名
导入其它配置
- import:在当前配置文件中导入其它配置文件
- 格式:
<beans>
<import />
</beans>
基本属性
<import resource="config.xml"/>
resource:加载的配置文件名
spring容器可以加载多个配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config1.xml","config2.xml");
Spring容器中的bean定义冲突问题
- 同id的bean,后定义的覆盖先定义的
- 导入配置文件可以理解为将导入的配置文件赋值粘贴对应位置
- 导入配置文件的顺序不同可能会导致最终程序运行结果不同
第三方资源配置
- 配置阿里开源的Druid数据库
代码
依赖坐标
<dependency><!--spring依赖-->
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency><!--msql依赖-->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency><!--druid依赖-->
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.24</version>
</dependency>
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root
spring核心配置文件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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
">
<context:property-placeholder location="classpath:jdbc.properties"/><!--加载配置文件-->
<bean name="druidDatasource" class="com.alibaba.druid.pool.DruidDataSource"><!--使用阿里的Druid数据库连接池-->
<property name="driverClassName" value="${driver}"/> <!--读取配置文件数据-->
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
</beans>
测试
package cn.cdw;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author DW-CHEN
* 测试使用阿里第三方的Druid数据库连接池
*/
public class Demo1 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
DruidDataSource druidDatasource = (DruidDataSource) applicationContext.getBean("druidDatasource");
System.out.println(druidDatasource);
}
}
Spring注解方式开发
- 启动注解扫描
<context:component-scan base-package="packageName"/>
注意
- 无论是注解格式还是xml配置格式,最终都是将资源加载到IOC容器中,差别仅仅是数据读取方式不同
- 从加载效率上来说注解优于xml配置文件
bean的定义
-
@Component,@Controller,@Service,@Repository:设置该类为spring管理的bean
-
@Controller,@Service,@Repository是@Component的衍生注解,功能和@Component一样
-
属性value(默认):定义bean的访问id
bean的作用域
- @Scope:设置该类作为bean对应的scope属性
- 属性value(默认):定义bean的作用域,默认为singleton
bean的生命周期
- @PostConstruct ,@PreDestroy:设置该类作为bean对应的生命周期方法
加载第三方资源
- @Bean:设置该方法的返回值作为spring管理的bean
- 属性value(默认):定义bean的访问id
注意:
- 因为第三方bean无法在源码上进行修改,使用@Bean解决第三方bean的引入问题
- 该注解用于替换xml配置中的静态工厂与实例工厂创建bean,不区分方法是否为静态方法或非静态方法
- @Bean所在类必须被spring扫描加载,否则该注解无法生效
bean的非引用类型属性注入
- @Value:设置对应属性的值或对应方法进行传参
- 属性value(默认):定义对应的属性值或参数值
注意:
- value值仅支持非引用类型数据,赋值时对方法的所有参数全部赋值
- value值仅支持读取properties文件中的属性值,通过类属性将properties中的数据传入类中
- value值支持SpEL
- @Valeu注解如果添加到属性上方可以省略set方法(set方法的目的是为了属性赋值)
bean的引用类型属性注入
- @Autowired,@Qualifier:设置对应属性的对象或对方法进行引用类型传参
- 属性required:定义该属性是否允许为null
注意:
- @Autowired默认按类型装配,指定@Qualifier后可以指定自动装配的bean的id
@Primary
- @Primary:设置类对应的bean按类型装配是优先装配
注意:@Autowired默认按类型装配,当出现相同类型的bean,使用@Primary提高按类型自动装配的优先级,多个@Primary会导致优先级设置无效
加载properties文件
- @PropertySource:加载properties文件中的属性值
- 属性value(默认):设置加载的properties文件名
- 属性ignoreResourceNotFound:如果资源未找到,是否忽略,默认为false
注意:不支持*通配格式,一旦加载,所有spring控制的bean中均可使用对应的属性值
纯注解格式
- @Configuration,@ComponentScan:设置当前类为spring核心加载类
- AnnotationConfigApplicationContext:加载纯注解格式上下文对象
注意
- 核心配置类用于替换spring核心配置文件,此类可以设置为空的,不设置变量和属性
- bean扫描工作使用注解@ComponentScan替换
第三方bean配置管理
@Import:导入第三方bean作为spring控制的资源
注意:
- @Import注解在同一个类上,仅允许添加一次,如果需要导入多个,使用数组的形式进行设定
- 在被导入的类中可以使用@Import导入其它资源
- @Bean所在的类可以使用导入的形式进入spring容器,无需声明为bean
依赖加载
- @DependsOn:控制bean的加载顺序,使其在指定的bean加载完毕后再加载
- 属性value:设置当前bean所依赖的bean的id
注意:
- 配置在方法上,使@DependsOn指定的bean优先于@Bean配置的bean进行加载
- 配置在类上,使@DependsOn指定的bean优先于当前类中所有@Bean配置的bean进行加载
- 配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载
@Order
- @Order:控制配置类的加载顺序
@Lazy
- @Lazy:控制bean的加载时机,使其延迟加载