1、初始Spring
1.1、简介
Spring:春天的意思,寓意给软件行业带来了春天。
2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,不断的丰富其内涵,发布了1.0正式版。
Spring 理念:使现有技术更加实用。整合了现有的框架技术。
Spring官网:http://spring.io/
官网下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/
GitHub地址: https://github.com/spring-projects
1.2、优点
- spring是一个开源的免费的框架(容器)!
- spring是一个轻量级的、非入侵式的框架!
- 控制反转(IOC)、面向切面编程(AOP)!
- 支持事务的处理,对框架整合的支持!
spring可以总结为一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!
1.3、spring需要的导入的maven依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
1.4、组成
spring框架是一个分层架构,由7个定义良好的模块组成。Spring模快构建在核心容器之上,核心容器定义了创建、配置和管理bean的方式。
2、IOC
2.1、IOC理论推导
根据我们以前的方式测试IOC的原型
新建一个空白的maven项目
分析实现
1、编写一个UserDao接口(持久层接口)
// 编写一个持久层接口
public interface UserDao {
public void getUser();
}
2、编写Dao层的实现类
//编写Dao层的实现类
public class UserDaolmpl implements UserDao{
//重写接口方法
public void getUser() {
System.out.println("默认获取用户数据");
}
}
3、编写UserService接口(服务层接口)
// 编写服务层接口
public interface UserService {
public void getUser();
}
4、最后写Service的实现类UserDaolmpl
//编写业务层的实现类
public class UserServicelmpl implements UserService {
//创建dao层的对象
private UserDaolmpl userDao =new UserDaolmpl();
public void getUser() {
//调用dao层的方法
userDao.getUser();
}
}
5、测试
public class MyTest {
public static void main(String[] args) {
//创建业务层实现类的对象
UserServicelmpl servicelmpl = new UserServicelmpl();
//调用业务层的方法
servicelmpl.getUser();
}
}
结果:
以上这是我们原来的方式
现在我们增加一个UserDao的实现类UserDaoMySqllmpl
public class UserDaoMySqllmpl implements UserDao {
public void getUser() {
System.out.println("MySql实现类获取用户数据");
}
}
我们要使用MySql的话,就需要去service实现类里面修改对应的实现
//编写业务层的实现类
public class UserServicelmpl implements UserService {
//创建dao层的mysql实现类对象
//用户实际调用的是业务层,dao层不需要接触
private UserDaoMySqllmpl userDaoMySql=new UserDaoMySqllmpl();
public void getUser() {
//调用dao层的方法
userDaoMySql.getUser();
}
}
如果再增加一个实现类Oracle,我们使用时又要去service实现类里面去修改对应的实现。假设我们的这种需求非常大,这种方式就不适用了,因为每次变动,都需要修改大量的代码,这种设计的耦合性太高,违背了编程的原理。
我们想该怎样解决这种问题呢?
我们可以在需要用到它的地方,不去实现它,而是留出一个接口,利用ser注入。我们去修改代码:
//编写业务层的实现类
public class UserServicelmpl implements UserService {
private UserDao userDao;
//利用set进行动态实现值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
//调用dao层的方法
userDao.getUser();
}
}
测试:
public class MyTest {
public static void main(String[] args) {
//创建业务层实现类的对象
UserServicelmpl servicelmpl = new UserServicelmpl();
servicelmpl.setUserDao(new UserDaolmpl());
//调用业务层的方法
servicelmpl.getUser();
//用mysql实现
servicelmpl.setUserDao(new UserDaoMySqllmpl());
servicelmpl.getUser();
}
}
比较:
在之前的业务中,用户的需求如果发生变化,我们就需要根据用户的需求去修改我们的代码。如果程序的代码量非常大,修改成本昂贵。
- 之前程序是主动创建对象!控制权在程序员手上。
- 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象,它只负责提供 一个接口。主动权交给了调用者。
这种思想从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低,可以更加专注的在业务的实现上。这就是IOC的原型。
2.2、IOC本质
控制反转IOC(Inversion of Control),是一种思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方。控制反转可以理解为:获得依赖对象的方式反转了。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection,DI)。
3、HelloSpring
1、导入依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
</dependencies>
2、编写一个实体类
public class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hello{" +
"name=" + name +
'}';
}
}
3、编写Spring文件,这里我们命名为:beans.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--这个bean来就是java对象,我们使用Spring来创建和管理-->
<bean id="hello" class="com.ljy.pojo.Hello">
<property name="name" value="lijinyang" />
</bean>
</beans>
4、编写测试类
public class MyTest {
public static void main(String[] args) {
//获取spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象都在spring中管理了,我们要使用直接取出来就可以
//getBean 参数就是spring配置文件中bean的id
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
}
根据这个案例我们可以明白:
- Hello对象是由spring文件创建的
- hello对象的属性是由spring容器设置的
这个过程就被称做控制反转
- 控制:谁来控制对象的创建?传统应用程序的对象是由程序本身控制创建的,使用spring后,对象是由spring来创建的。
- 反转:程序本身不创建对象,而变成被动的接收对象
- 依赖注入:利用set方法来进行注入的
IOC是一种编程思想,由主动的编程变成被动的接受。
这块可以通过newClassPathXmlApplicationContext去浏览一下底层原码
理解了控制反转之后,我们想要实现不同的操作,只需要在xml配置文件中进行修改。所谓的ioc,也就是:对象由Spring来创建,管理,装配。
4、IOC创建对象的方式
1、使用无参构造创建对象
无参构造就是默认的方式,必须使用set方法
2、使用有参构造创建对象
实体类可以不写set方法
- 方式一、下标赋值
!--第一种:下标赋值-->
<bean id="user" class="com.ljy.pojo.User">
<constructor-arg index="0" value="lijinyang"/>
</bean>
- 方式二、类型
<!--方式二、类型-->
<bean id="user" class="com.ljy.pojo.User">
<constructor-arg type="java.lang.String" value="李锦阳"/>
</bean>
要是有参构造方法传两个参数的话就不适用
- 方式三、参数名
<!--方式三、参数名-->
<bean id="user" class="com.ljy.pojo.User">
<constructor-arg name="name" value="阳哥666"/>
</bean>
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!
5、Spring的配置
别名
alias设置别名,为bean设置别名,可以设置多个别名
<alias name="UserT" alias="UserHAHA">
Bean的配置
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name就是别名
name可以设置多个别名,可以用逗号 分号 空格 隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象
class是bean的全限定名 包名+类名
-->
<bean id="hello" name="hello2 hello222 hello3" class="com.ljy.pojo.Hello">
<property name="name" value="lijinyang">
</bean>
import
团队的合作通过import来实现,可以将多个配置文件导入合并为一个
将多个配置文件,使用import标签,导入applicationContext.xml中
<import resource="zhangsan.xml"/>
<import resource="lisi.xml"/>
<import resource="wangwu.xml"/>
在使用的时候,使用总的配置文件applicationContext.xml即可。