Spring基础
Spring Framework:Spring技术的基础框架
Springboot:简易开发
Springcloud:微服务的开发
Spring Framework为Spring所有框架中的最基础的项目
1、Core Container:核心容器
(IOC控制反转,DI依赖注入)
2、整合mybatis(Data Access:数据访问,Data Integration:数据集成)
3、Aop:面向切面编程
Aspects:Aop思想进行实现
4、事务应用开发
Web:web开发
Test:单元测试与集成测试
底层核心思想:(解决代码存在的耦合度偏高的问题)
解决:使用对象的时候,不去主动的使用new生成对象,转换为由外部提供对象
一、IoC:控制反转–》解耦合
解释:对象不用自身进行创建,将对象的
创建控制权转移
到
外部
,这样的思想就是控制反转
“外部”–》IOC容器(负责对于对象进行创建,初始化等一系列的工作,别创建,管理的对象放在对应的IOC容器中统称为**Bean
**)
二、DI依赖注入
IoC容器中两个Bean对象需要依赖在一起才能够执行,就需要进行依赖注入的思想
解耦的步骤
1、使用IoC容器管理Bean(IoC)
2、在IoC容器内将所有有依赖关系的Bean对象进行关系绑定(DI)
IoC具体实现:
管理:Service和Dao
将被管理的对象告诉IoC容器(配置)
如何获取IoC容器(接口)
IoC容器获取之后怎么获取其中的Bean对象(接口方法)
导入相应的配置(pom.xml)
DI具体实现:
通过ApplicationContext.xml的Spring的配置文件进行相关的配置
通过property标签嵌入到Bean中进行依赖的注入
<!-- 通过property标签 name:相关的值为创建的Dao的对象的名字->private BookDao bookDao; ref:表示引用的Bean的id --> <property name="bookDao" ref="bookDao"/>
App主方法的实现调用:
//获取applicationContext容器
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过配置文件进行调用,获取Bean对象(返回的为Object类型)--》需要强行转换为对象的类型
BookService bookService=(BookService)ac.getBean("bookService");
//调用方法
bookService.save();
Bean对象的基础配置
<bean id="bookDao" name="dao1 dao2" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"/>
Bean对象配置中的id为Bean对象的唯一标识,name为取别名的意思,scope为这个Bean对象的作用域是否单例(不可重复)
Bean的实例化
1、调用的它的空参的构造方法–》常用方法进行实例
<!--方式一:构造方法实例化bean-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
Spring中的代码异常报错,从下往上一次排除
2、通过一个工厂类中的静态方法进行实例化
<!--方式二:使用静态工厂实例化bean-->
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
//静态工厂创建对象
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
System.out.println("factory setup....");
return new OrderDaoImpl();
}
}
3、通过实例工厂实例化(不用设为static方法)
//实例工厂创建对象
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
<!--方式三:使用实例工厂实例化bean-->
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
4、通过factoryBean实例化Bean
UseDao.java
public interface UserDao {
public void save();
}
UserDaoImpl.java
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("user dao save ...");
}
}
UserDaoFactoryBean.java(实现FactoryBean<泛型类型:要实现的Bean对象>的接口)
//FactoryBean创建对象
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
public Class<?> getObjectType() {
return UserDao.class;
}
}
进行Bean的配置:
<!--方式四:使用FactoryBean实例化bean-->
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
调用执行
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
Bean的生命周期(init,destroy)
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
//表示bean初始化对应的操作
public void init(){
System.out.println("init...");
}
//表示bean销毁前对应的操作
public void destory(){
System.out.println("destory...");
}
}
<!--init-method:设置bean初始化生命周期回调函数-->
<!--destroy-method:设置bean销毁生命周期回调函数,仅适用于单例对象-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
具体实现:
1、创建对象(进行内存分配)
2、执行构造方法
3、执行属性注入(set操作)
4、执行bean初始化方法
5、使用bean(执行相关的业务操作)
6、关闭、销毁容器
7、执行bean销毁方法
依赖注入
根据注入方式分为
1、setter方法进行注入(自己在编写模块的时候推荐使用)
2、构造器进行注入
注入的类型分为有引用类型和简单类型(基本的数据类型和String)
Setter注入:通过标签property
(引用类型参数为name,ref)
(基本类型参数为name,value)
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
//setter注入需要提供要注入对象的set方法
public void setConnectionNum(int connectionNum) {
this.connectionNum = connectionNum;
}
//setter注入需要提供要注入对象的set方法
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
public void save() {
System.out.println("book dao save ..."+databaseName+","+connectionNum);
}
}
public class BookServiceImpl implements BookService{
private BookDao bookDao;
private UserDao userDao;
//setter注入需要提供要注入对象的set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//setter注入需要提供要注入对象的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
userDao.save();
}
}
在bean的配置文件中实现类型注入(简单类型通过value指定值,引用类型通过ref指定绑定的引用类型–》配置的bean对象的id)
普通类型:
property标签:设置注入属性
name属性:设置注入的属性名,实际是set方法对应的名称
value属性:设置注入简单类型数据值
引用类型:
property标签:设置注入属性
name属性:设置注入的属性名,实际是set方法对应的名称
ref属性:设置注入引用类型bean的id或name
<!--注入简单类型-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<!--property标签:设置注入属性-->
<!--name属性:设置注入的属性名,实际是set方法对应的名称-->
<!--value属性:设置注入简单类型数据值-->
<property name="connectionNum" value="100"/>
<property name="databaseName" value="mysql"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<!--注入引用类型-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<!--property标签:设置注入属性-->
<!--name属性:设置注入的属性名,实际是set方法对应的名称-->
<!--ref属性:设置注入引用类型bean的id或name-->
<property name="bookDao" ref="bookDao"/>
<property name="userDao" ref="userDao"/>
</bean>
构造器的注入:使用标签constructor-arg(其中的参数说明任然不变)
(引用类型参数为name,ref)
(基本类型参数为name,value)
public class BookServiceImpl implements BookService{
private BookDao bookDao;
private UserDao userDao;
public BookServiceImpl(BookDao bookDao, UserDao userDao) {
this.bookDao = bookDao;
this.userDao = userDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
userDao.save();
}
}
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
public BookDaoImpl(String databaseName, int connectionNum) {
this.databaseName = databaseName;
this.connectionNum = connectionNum;
}
public void save() {
System.out.println("book dao save ..."+databaseName+","+connectionNum);
}
}
<!--
标准书写
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
根据构造方法参数名称注入
<constructor-arg name="connectionNum" value="10"/>
<constructor-arg name="databaseName" value="mysql"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
-->
<!--
解决形参名称的问题,与形参名不耦合
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
根据构造方法参数类型注入
<constructor-arg type="int" value="10"/>
<constructor-arg type="java.lang.String" value="mysql"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>-->
<!--解决参数类型重复问题,使用位置解决参数匹配-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<!--根据构造方法参数位置注入-->
<constructor-arg index="0" value="mysql"/>
<constructor-arg index="1" value="100"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
bean的自动装配(通过bean标签的属性值,autowire=“”)实现byType通过引用对象类型进行注入
<bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="org.example.service.impl.BookServiceImpl" autowire="byType"/>
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
集合类型的setter注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<!--数组注入-->
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<!--list集合注入-->
<property name="list">
<list>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>chuanzhihui</value>
</list>
</property>
<!--set集合注入-->
<property name="set">
<set>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>boxuegu</value>
</set>
</property>
<!--map集合注入-->
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
<!--Properties注入-->
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
</bean>
public class BookDaoImpl implements BookDao {
private int[] array;
private List<String> list;
private Set<String> set;
private Map<String,String> map;
private Properties properties;
public void setArray(int[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void save() {
System.out.println("book dao save ...");
System.out.println("遍历数组:" + Arrays.toString(array));
System.out.println("遍历List" + list);
System.out.println("遍历Set" + set);
System.out.println("遍历Map" + map);
System.out.println("遍历Properties" + properties);
}
}