Spring Framework 的特点Spring 框架具有以下几个特点。(spring官网)
- 方便解耦,简化开发Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理。
- 方便集成各种优秀框架Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis 等)的直接支持。
- 降低 Java EE API 的使用难度Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些 API 应用的难度大大降低。
- 方便程序的测试Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序。
- AOP 编程的支持Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。
- 声明式事务的支持只需要通过配置就可以完成对事务的管理,而无须手动编程。
application.xml
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" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--Spring框架主要做的一件事情 就是对象的创建管理 -->
<!--每一个bean标签 就表示你要声明创建一个指定类的对象-->
<!--<bean id="us" class="com.itheima.service.impl.UserServiceImpl" />-->
<!--bean标签:表示声明创建一个类的对象 位置:beans根标签中 作用:声明创建对象
属性:id:设置对象的唯一标识 也就相当于对象的名称
class:声明要创建哪个类的对象 一般要写具体的实现类 不能写接口和抽象类
name : 设置对象别名 也是相当于对象的名称 可以设置多个
多个别名之间可以使用 逗号 空格 分号隔开
scope :设置对象的作用范围
singleton:单例,默认 Spring默认创建这个类的对象 在程序运行期间有且仅有一个
优点:节省内存资源
prototype:多例,需要设置,每次从Spring工厂获取对象都会创建一个新的出来
lazy-init :延迟加载
对于单例模式 :默认为false 不延迟加载,在加载配置文件时就实例化对象,
设置true时,getBean获取对象时才实例化对象
对于单例模式 : 无论改为true|false,都是在获取对象时实例化对象
bean的生命周期:
init-method:对象初始化时调用的方法
singleton: 单例 在项目启动,创建Spring工厂对象的同时 就会创建并初始化Spring容器中要管理的对象
prototype:多例,在从Spring工厂中要对象的时候才会创建 ,要一次就创建一次
destroy-method:对象销毁时调用的方法
singleton: 单例 在项目停止,关闭或销毁Spring工厂对象的同时 会销毁Spring容器中管理的对象
prototype:多例
由于Spring创建的多例模式对象 不由Spring工厂管理 所以Spring工厂对象销毁 对象不会销毁而是等到这个对象没有再被引用时,会由JVM的垃圾回收 自动销毁回收
一般使用Spring创建对象时 就使用它默认创建的单例模式的对象 -->
<!--spring创建bean的三种方式-->
<!--方式一:直接使用对象的无参构造函数 使用反射技术进行创建 【常用 推荐】-->
<bean id="us" class="com.itheima.service.impl.UserServiceImpl"/>
<!--静态工厂和实例工厂创建对象【了解】
注意:
1.不管是使用静态工厂创建还是实例工厂创建 对象的创建是由别人已经写好的工厂类完成的 Spring得到别人工厂类创建好的对象进行管理
2.出现原因:a:Spring程序兼容老项目 b:Spring程序整合第三方技术 eg:MyBatis -->
<!--方式二:静态工厂创建 Spring工厂去调用被人写好的静态工厂创建对象 放到IOC容器中管理 对象创建:别的静态工厂创建的 对象管理:Spring工厂|IOC容器-->
<!--Spring 将StaticFactory静态工厂类调用getInstance方法创建的对象us2放到IOC容器中管理-->
<bean id="us2" class="com.itheima.factory.StaticFactory" factory-method="getInstance"></bean>
<!--方式三:实例工厂创建 Spring工厂去调用被人写好的实例工厂创建对象 放到IOC容器中管理 对象创建:别的实例工厂创建的 对象管理:Spring工厂|IOC容器-->
<!--创建实例工厂对象instanceFactory-->
<bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"/>
<!--Spring 将实例工厂对象instanceFactory调用getInstance方法创建的对象us3放入到IOC容器中管理-->
<bean id="us3" factory-bean="instanceFactory" factory-method="getInstance"/>
<!-- 方式四:实例工厂优化FactoryBean Spring提供了一个接口FactoryBean规范了实例工厂类中代码的编写 从而可以简化bean的配置
使用场景:【Spring整合第三方技术时 会经常用到】如Spring整合MyBatis:
要创建SqlSessionFactory对象 在MyBatis中就提供了SqlSessionFactoryBean
SqlSessionFactoryBean实例工厂类 实现了 FactoryBean接口
Spring就可以直接调用 SqlSessionFactoryBean,执行getObject方法 得到SqlSessionFactory对象放入到IOC容器中管理 -->
<!--描述:Spring 调用UserServiceFactoryBean执行它的getObject方法 得到UserService类型对象 放入到IOC容器中管理 并且对象是单例的-->
<bean id="us4" class="com.itheima.factory.UserServiceFactoryBean" /></beans>
注入方式:setter注入和构造器注入
setter注入:
类中需要有对应属性的set方法
property标签:为对象的属性赋值属性:
name:属性名称
value:为属性设置简单类型数据–>设置不是IOC容器中管理的数据
ref:为属性设置引用类型数据 -->设置IOC容器中管理的对象
注意:
value属性和ref属性不能同时使用 两者只能同时使用一个
使用set注入比较灵活 可以注入多个 也可以一个都不注入
注入简单类型:基本数据类型+String
<bean id="us1" class="com.itheima.service.impl.UserServiceImpl01">
<property name="username" value="黄帅"/>
<property name="age" value="20"/>
</bean>
注入引用类型:注入IOC容器中管理的对象数据到一个类中
<bean id="ud2" class="com.itheima.dao.impl.UserDaoImpl02"/>
<bean id="us2" class="com.itheima.service.impl.UserServiceImpl02">
<property name="userDao" ref="ud2"/>
</bean>
构造器注入
类中需要有对应参数的构造方法constructor-arg标签:设置构造方法参数 可以有多个 写在bean标签中
属性:
name:构造方法参数名称
value:注入简单类型数据
ref:注入引用类型数据 注入IOC容器中管理的对象
带2个参数的构造函数 username address
<bean id="us1" class="com.itheima.service.impl.UserServiceImpl03">
<constructor-arg name="username" value="张三"/>
<constructor-arg name="address" value="深圳"/>
</bean>
带3个参数的构造函数 username address userDao
<bean id="ud" class="com.itheima.dao.impl.UserDaoImpl02"></bean>
<bean id="us2" class="com.itheima.service.impl.UserServiceImpl03">
<constructor-arg name="username" value="张三"/>
<constructor-arg name="address" value="深圳"/>
<constructor-arg name="userDao" ref="ud"/>
</bean>
p命名空间注入:
基于setter注入,对setter注入简化,要求类中的属性必须提供set方法
使用步骤:
在applicationContext.xml中引入p命名空间xmlns:p=“http://www.springframework.org/schema/p”
在bean的开始标签中使用 p:属性名称=简单类型值 p:属性名称-ref=bean的Id
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ud" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="us" class="com.itheima.service.impl.UserServiceImpl04" p:username="李四" p:address="惠州" p:userDao-ref="ud" />
DI自动装配注意:
自动装配用于引用类型依赖注入,不能对简单类型进行操作
使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用,(类中变量名和bean中id相同)
自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
<bean id="ud" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="us" class="com.itheima.service.impl.UserServiceImpl" autowire="byType">
等价于:<bean id="us" class="com.itheima.service.impl.UserServiceImpl"
<property name="userDao" ref="ud"/>
</bean>DI
注入集合类型数据
注意:
注入集合数据时,如果注入的是数组、List集合、Set集合 可以使用array、set、list三个标签中的任意一个都可以
如果注入的是Map集合或properties,两种集合的数据注入方式可以互换
<bean id="us6" class="com.itheima.service.impl.UserServiceImpl06">
<!--数组-->
<property name="array">
<array>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</array>
</property>
<!--list-->
<property name="list">
<list>
<value>张三1</value>
<value>李四1</value>
<value>王五1</value>
</list>
</property>
<!--set-->
<property name="set">
<set>
<value>张三2</value>
<value>李四2</value>
<value>王五2</value>
</set>
</property>
<!--map-->
<property name="map">
<map>
<entry key="CN" value="中国"></entry>
<entry key="JP" value="小日本"></entry>
<entry key="USA" value="抽口感"></entry>
</map>
</property>
<!--properties-->
<property name="properties">
<props>
<prop key="sz">深圳</prop>
<prop key="dg">东莞</prop>
<prop key="hz">惠州</prop>
</props>
</property>
</bean>
引入外部properties文件
<context:property-placeholder location="classpath:db.properties"/>
使用:${配置文件中的key}获取key对应的数据
注意:
引入外部配置文件时,key不要设置为username(系统不区分大小写,例如userName也不行),因为username系统已存在该名称
解决方式:
1. 加一个下划线,user_name,
2. 在引入配置文件的地方设置local-override属性为"true" ,默认为false
<context:property-placeholder local-override ="true" location="classpath:db.properties"/>
import标签 引入子配置文件
引入resources文件夹中的spring-dao.xml文件,可以引用spring-dao.xml文件配置的交由IOC容器管理的类
<import resource="classpath:spring-dao.xml"/>