初识:Spring 思想
Spring Framework (Spring 框架)
是spring最基础的项目,是其他项目的根基
架构图
- 核心容器
- 整合mybatis
- 事务
重点!!!!
IOC(控制反转) DI(依赖注入)
IOC理解:
是一个理论,概念,思想。把对象的创建,赋值,管理工作都交给代码之外的容器实现, 也就是对象的创建是有其它外部资源完成,
这样做实现了解耦合。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式,在Spring中实现控制反转的是IOC容器,
其实现方法是依赖注入(DI)
正转与反转
正转:对象的创建、赋值等操作交由程序员手动完成,即使用类似new Xxx(Xxx Xxx)、Xxx.setXxx()语句完成对象的创建与赋值,缺点是一旦程序功能发生改变,涉及到的类就要修改代理,耦合度高,不便于维护和管理。
反转:对象的创建、赋值等操作交由代码之外的容器实现,有容器代替程序员完成对象的创建、赋值;且当程序功能发生变化时,只需要修改容器的配置文件即可。
bean的基本配置
基础配置
起别名
在name中给别名,;,空格分隔都可以
service(表现层) dao(数据层) utils(工具)
bean的创建方式(实例化)
堆栈信息(报错的信息)
- 构造方法
- 静态工厂实例化bean(常见的方法) 兼容早期的(了解)
IOC配置文件
<!--
声明bean(告诉spring要创建某个类的对象)
1、id:自定义名称,唯一值,spring通过该id的属性值找到对象
2、class:要创建类的全限定类名
3、下述的声明语句在spring底层类似与执行了以下代码:
SomeService service = new SomeServiceImpl();
4、对象的保存:
spring将对象保存到内部的map中,map.put(id值,对象)
map.put("someService",new SomeServiceImpl())
5、一个bean标签声明一个java对象
6、spring容器根据bean标签创建对象,尽管存在class属性相同的bean标签,只要是id值不同,
spring容器就会创建该class的对象
-->
<bean id="someService" class="com.mms.service.impl.SomeServiceImpl"/>
<bean id="someService2" class="com.mms.service.impl.SomeServiceImpl"/>
<!--使用spring来创建对象,在spring都称为bean
类型 变量名 = new Hello()
id = 变量名
class = new 的对象
property相当于给对象中的属性设置一个值
ref:引用spring容器中创建好的对象
value:具体的值
-->
<!--
spring容器也可以创建非自定义类的对象,例如java.lang.String类的对象,只要指定了
class属性,spring容器就可以创建该类的对象
-->
<bean id="myString" class="java.lang.String"/>
总结
spring配置文件中一个bean标签就代表一个对象,该对象有bean标签的id值唯一标识,
从spring拿对象是使用getBean(“bean标签的id值”)
spring默认是使用类的无参构造来创建对象的
set注入要求
JavaBean必须要有set方法,因为ioc容器是使用javabean的set方法进行属性赋值的
spring容器调用的是setXxx()方法,而不管对象是否具有Xxx属性(
即对象没有的属性只要有set方法也可以实现注入),Xxx不区分大小写
<!--
1、简单类型使用property和value标签给对象属性赋值
2、简单类型:8个基本类型+String
3、当spring容器加载到这一行时会在创建完对象的同时使用对象的set方法给属性赋值,底层
调用的是对象的set方法
4、spring容器调用的是setXxx()方法,而不管对象是否具有Xxx属性,Xxx不区分大小写
-->
非简单类型属性的赋值(set注入)
上文中的set注入使用property标签的name和value属性给对象属性赋值,但是value只是给简单类型属性赋值,对于非简单类型我们是使用property标签的name和ref属性给对象属性赋值。
构造注入
顾名思义,构造注入是使用javabean的构造方法进行属性的赋值的。与set注入一样,构造注入要求javabean必须提供构造方法,且必须是有参构造(如果是无参构造还怎么给属性赋值,对吧),构造注入使用较少,了解就可以了,我们一般使用set注入。
<!--
构造注入
1、使用constructor-arg标签完成构造注入
2、构造注入方式一:根据形参名字
3、构造注入方式二:根据形参顺序,默认下标从0开始递增
-->
简单类型的注解di实现
简单类型的注入使用@Value注解实现,哪些简单类型要设置属性值,直接在简单类型属性声明语句的上面加入注解@Value即可,并在@Value的括号内键入属性值,注意不论简单类型属性的数据类型,均由双引号将属性值括起来。例如之前的Student类使用注解注入如下。
引用类型的注解di实现
引用类型的注入使用@Autowired注解完成。
@Autowired
@Autowired是spring提供的属性赋值,用于给引用类型赋值,有byName和byType两种方式,默认使用byType方式自动注入
若是要强制至于byName方式,要在@Autowired注解下面加入 @Qualifier(value = “bean的id”)注解,若程序在给引用类型注入时在xml文件中找不到 该id的bean标签或者手找不到该id的@Component注解,则报错;若不想让程序在赋值失败时报错,可以在@Autowired注解的required属性值置为false
我的笔记
IOC 使用对象时,由主动new对象转换为由外部提供对象。 此过程中对象的创建控制权由程序转移到外部
称为控制反转。
Spring 提供了一个容器 IOC容器!! 用来充当外部
IOC容器负责对象的创建、初始化 被创建的对象称为bean
建立bean与bean之间的关系称为依赖注入
目的:为了解耦
通过IOC容器管理bean(对象)
导入Spring包
<dependencies>
<!--导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
配置bean的
<!--
id 表示配置的bean名称 (相当于new出来的名字)
class 表示配置得bean的类型(相当于要new的对象)
-->
bean相当于创建对象
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
参照 private String username;
private User user;
property 相当于设置成员变量
<!--配置server与dao的关系
property标签:表示配置当前bean的属性
name属性:表示配置哪一个具体的属性 (相当于起的名字)
ref属性:表示参照哪一个bean (用于引用数据类型)什么类型
value属性: 用于基本数据类型
-->
<property name="bookDao" ref="bookDao"/>
</bean>
bean的实例化(三种)
构造方法
<!--方式一:构造方法实例化bean-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
使用的是无参构造方法
先执行无参构造方法,再执行调用的方法
(无参构造方法不存在,会报错)
静态工厂方法
会创建对应的工厂类
public interface OrderDao {
public void save();
}
public class OrderDaoImpl implements OrderDao {
public void save() {
System.out.println("order dao save ...");
}
}
//静态工厂创建对象
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
System.out.println("factory setup....");
return new OrderDaoImpl();
}
}
<!--方式二:使用静态工厂实例化bean-->
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
public class Test{
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
orderDao.save();
}
}
实例工厂方法
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("user dao save ...");
}
}
//实例工厂创建对象
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"/>
public class Test{
public static void main(String[] args) {
// //创建实例工厂对象
// UserDaoFactory userDaoFactory = new UserDaoFactory();
// //通过实例工厂对象创建对象
// UserDao userDao = userDaoFactory.getUserDao();
// userDao.save();
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
}
}
bean的生命周期
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初始化生命周期回调函数,此处填写init方法名-->
<!--destroy-method:设置bean销毁生命周期回调函数,仅适用于单例对象,此处填写destory方法名-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
依赖注入
set注入(简单类型、引用类型–常用) (推荐)
简单类型
构造器注入(简单类型、引用类型)
简单类型
参数
集合注入
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<property name="list">
<list>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>chuanzhihui</value>
</list>
</property>
<property name="set">
<set>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>boxuegu</value>
</set>
</property>
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
也可以看上面的两个网址