# 1
、Spring
## 1.1、简介
Spring框架是由于软件开发的复杂性而创建,是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架
==目的==就是为了解决企业应用开发的复杂性
==理念==使现有的技术更加容易使用,本身就是一个大杂烩,整合了现有的技术框架
==功能==使用基本的JavaBean代替EJB,提供更多的企业应用功能
## 1.2、优点
- Spring是一个开源的免费框架(容器)
- Spring是一个轻量级的[^非常小,引入几个jar包即可使用]、非入侵式的框架[^引用该框架不会影响原有代码,直接使用即可]
- ==控制反转(IoC)和面向切面编程(AOP)(Spring的核心内容)==
- 支持声明式事务处理
## 1.3、构成
![](https://img2018.cnblogs.com/blog/480452/201903/480452-20190318225849216-2097896352.png) 由7大模块构成
## 1.4、拓展
- Spring boot
- 是一个快速开发的脚手架
- 基于Spring boot可以快速开发单个微服务
- ==约定大于配置==
- Spring cloud
- Spring cloud是基于Spring boot实现的
- Spring boot是将Spring boot构建的东西协调在一起
==学习Spring boot的前提是掌握Spring和SpringMVC==
# 2、IoC理论推导
```java
public interface UserDao {
void getUser();
}
```
```java
public class UserDaoImpl implements UserDao {
public void getUser() {
System.out.println("默认获取用户的数据");
}
}
```
```java
public class MysqlUserDaoImpl implements UserDao {
public void getUser() {
System.out.println("mysql请求");
}
}
```
```java
public interface UserService {
void getUser();
}
```
没有使用==控制反转理念:==
```java
public class UserServiceImpl implements UserService {
private UserDao userDao=new UserDaoImpl();//直接将要使用的对象写死在程序中
public void getUser() {
userDao.getUser();
}
}
```
````java
public class MyTest {
public static void main(String[] args) {
UserService userServiceImpl=new UserServiceImpl();
userServiceImpl.getUser();//输出固定,需要调用别的类时只能修改程序实例化的对象
}
}
````
使用了==控制反转:==
````java
public class UserServiceImpl implements UserService {
private UserDao userDao;//不用在程序中实例化对象
public void setUserDao(UserDao userDao) {//通过set方法获取需要用的接口
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
````
````java
public class MyTest {
public static void main(String[] args) {
UserService userServiceImpl=new UserServiceImpl();
((UserServiceImpl) userServiceImpl).setUserDao(new MysqlUserDaoImpl());//用户调用set方法实例化自己所需要的对象,不需要再更改程序
userServiceImpl.getUser();
}
}
````
有无使用==控制反转==的最大区别在于==创建对象的主动权==的变化:
- 没有使用的控制权在程序员手中,需要更改源程序
- 使用了的在用户手中,只需要更改调用set方法地参数
- set方法让程序实例化对象不具有主动性,等到用户使用程序,才能通过set方法注入需要实例化的对象
# 3、IoC的本质
**==IoC是一种设计思想,DI(依赖注入)才是IoC的其中一种实现方法==**,可以说IoC这种设计思想为的就是实现低耦合
# 4、DI依赖注入
## 4.1、概念
依赖注入(DI)是一个过程,通过该过程,对象只能通过==构造函数参数,工厂方法的参数或在构造或创建对象实例==后在对象实例上设置的属性来定义其依赖关系(即,与它们一起工作的其他对象)。
- 依赖:bean对象的创建依赖于spring容器
- 注入:bean对象中的所有属性,都由容器注入
## 4.2、方式
### 4.2.1、==基于Setter的依赖注入(默认)==
通过调用无参的构造方法或无参的static工厂方法实例化bean后,在bean上调用setter方法来完成。
- 复杂类型
```java
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Address{" +
"address='" + address + '\'' +
'}';
}
}
```
- 真实测试对象
```java
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties info;
//补全get set方法
}
```
- beans.xml
```xml
<bean id="student" class="com.jk.pojo.Student">
<property name="name" value="hjk"/>
<property name="address" ref="address"></property>
<!--数组类型-->
<property name="books">
<array>
<value>数学</value>
<value>语文</value>
</array>
</property>
<!--map-->
<property name="card">
<map>
<entry key="身份证" value="44444444444"></entry>
<entry key="学号" value="1111111111"></entry>
</map>
</property>
<!--list-->
<property name="hobbys">
<list>
<value>游泳</value>
<value>打代码</value>
</list>
</property>
<!--set-->
<property name="games">
<set>
<value>gta</value>
</set>
</property>
<!--Properties-->
<property name="info">
<props>
<prop key="gta">gta</prop>
</props>
</property>
</bean>
<bean id="address" class="com.jk.pojo.Address">
<property name="address" value="珠海"></property>
</bean>
```
### 4.2.2、有参构造函数的依赖注入
````java
public UserServiceImpl(String name){
System.out.println(name);
}
````
- 构造函数参数下标索引
```xml
<constructor-arg index="0" value="hjk"/>
```
- 构造函数类型索引==(不建议)==
````xml
<constructor-arg type="java.lang.String" value="hjk"/>
````
- 构造函数参数名称索引
```xml
<constructor-arg name="name" value="hjk"/>
```
### 4.2.3、拓展方式
1. p命名空间注入
属于set方式注入的一种,省略了<property></property>,直接用p:xxx代替,需要在<beans>中引入约束:
```xml-dtd
xmlns:p="http://www.springframework.org/schema/p"
```
可以写成:
```xml
<bean name="classic" class="com.example.ExampleBean">
<property name="email" value="[emailprotected]"/>
</bean>
<bean name="p-namespace" class="com.example.ExampleBean" p:email="[emailprotected]"/>
```
2. c命名空间注入
属于构造器方式注入的一种,省略了<constructor-arg></constructor-arg>,直接用c:xxx代替,需要在<beans>中引入约束:
```xml-dtd
xmlns:c="http://www.springframework.org/schema/c"
```
```xml
<bean id="thingOne" class="x.y.ThingOne">
<constructor-arg ref="thingTwo"/>
</bean>
<bean id="thingOne" class="x.y.ThingOne" c:thingTwo-ref="thingTwo"></bean>
```
# 4.3、总结
目录
### 4.2.1、==基于Setter的依赖注入(默认)==
在配置文件beans.xml被加载时,容器中管理的所有对象就已经被初始化