Spring基础(一)

Spring简介

Spring由《Expoer One-on-one j2eedevelopment and Design》文章核心延申而来。

2003年推出Spring:Spring的两大核心 IOC、APO

现在推出的Spring data、Spring boot、Spring cloud、Spring framework。这些都是由Spring延申而来的。

Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架。

  • spring的设计理念:使先有的技术更加容易使用(简化企业级开发)。本身是一个大杂烩,整合了先有的技术框架。

  • SSH:struct2 + spring + hibernate

  • SSM:springMVC + spring + mybatis

(spring是一个融合剂)

spring官网:https://spring.io/projects/spring-framework#overview

spring官方下载地址:https://maven.springframework.org/release/org/springframework/spring/

spring官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html

GitHub地址:https://github.com/spring-project/spring-framework

spring中文文档:https://www.docs4dev.com/docs/zh/spring-framework/4.3.21.RELEASE/reference/spring-introduction.html

spring优点:

  • spring是一个免费的框架。
  • spring是一个轻量级的、非入侵式的框架(引入spring后不会改变代码原来的情况)。
  • 控制反转(IOC)、面向切面编程(AOP)
  • 支持事务处理,对框架整合的支持

spring弊端:

  • 配置十分繁琐。

搭建Spring环境

Manen依赖:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>

Spring七大模块

在这里插入图片描述

Spring的学习路线
在这里插入图片描述

现代java开发就是基于spring开发。

  • Spring boot
    • 是一个快速开发的脚手架
    • 基于spring boot可以快速开发单个的微服务。(就是一个小模块)
    • spring boot开发中约定大于配置
  • Spring Cloud
    • spring cloud是及用户spring boot实现的。

IOC理论

之前的业务使用:

  1. Dao层接口
  2. DaoImpl实现类
  3. Service层接口
  4. ServiceImpl实现类

在我之前写的代码中,service层调用dao层是固定写死的。也就是一个业务方法中创建一个固定的dao类使用。这种写法是有缺陷的,用户需求改变会影响我们的代码。程序代码量大的话,修改一次的成本就非常大!

例如:

// 原来的代码
public interface UserDao {
    void print();
}

public class UserDaoImpl implements UserDao{
    @Override
    public void print() {
        System.out.println("使用了UserDao");
    }
}

public interface UserService {
    void userServicePring();
}

public class UserServiceImpl implements UserService{
    private UserDaoImpl userDao;
    @Override
    public void userServicePring() {
        userDao = new UserDaoImpl();
        userDao.print();
    }
}

public class MyTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl(userDao);
        userService.userServicePring();
    }
}

如果我们增加一个UserDaoUseOracleImpl(使用Oracle进行数据库连接,其中的方法与UserDao一模一样),那么我们就必须重新修改UserServiceImpl中的代码了,这时非常不好的。

public class UserDaoUseOracleImpl implements UserDao{
    @Override
    public void print() {
        System.out.println("使用了UserDaoUseOracle");
    }
}
public class UserServiceImpl implements UserService{
    private UserDaoUseOracleImpl userDao;
    @Override
    public void userServicePring() {
        userDao = new UserDaoUseOracleImpl();
        userDao.print();
    }
}

动态注入(IOC原型)

我们可以利用set实现动态值的注入,这样就不用修改service层的代码了。

public interface UserDao {
    void print();
}

public class UserDaoImpl implements UserDao{
    @Override
    public void print() {
        System.out.println("使用了UserDao");
    }
}

public class UserDaoUseOracleImpl implements UserDao{
    @Override
    public void print() {
        System.out.println("使用了UserDaoUseOracle");
    }
}

public interface UserService {
    void userServicePring();
}

public class UserServiceImpl implements UserService{
    private UserDao userDao;
    @Override
    public void userServicePring() {
        userDao.print();
    }
    
    public void setUserDao(UserDao userDao){
        this.userDao = userDao
    }
}

public class MyTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoImpl());
        userService.userServicePring();
        userService.setUserDao(new UserDaoUseOracleImpl())
        userService.userServicePring();
    }
}
  • 之前,程序是主动创建对象的,控制权在程序上。
  • 使用set注入后,控制权在用户程序员手中。

这种思想,从本质上解决了问题,我们业务程序员不需要再管理对象的创建了(由用户程序员创建)。降低了系统的耦合性,可以更加专注的放在业务实现上。

Spring底层大量用到了这种注入的思想!使得用户程序员创建对象底层代码不需要变动,提高了动态性。

IOC本质:控制反转是一种思想,使用控制反转后对象的创建移交给第三方(控制反转本质就是获取依赖对象的方式反转了:原来是程序创建依赖对象,现在是用户创建依赖对象)

IOC有很多实现方式,DI(依赖注入)只是其中一种。
在这里插入图片描述

控制反转是一种通过描述(XML或注解)并通过第三方生成特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(DI)

例如之前写的小例子:Service类就类似一个IOC容器,通过set注入生成不同功能的service对象。

通过上述所示:Spring可以管理对象(组件)

Hello Spring

一个简单的spring demo:

  1. 创建一个Bean类
    • 注意Bean必须拥有set、get方法(因为依赖注入是利用set方法注入的)
public class Hello {
    private String name;
    
    public Hello() {
    }

    public Hello(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "name='" + name + '\'' +
                '}';
    }
}
  1. 配置Bean的xml配置文件(用来配置Bean对象)
    • 一个bean相当于一个对象,id为逻辑对象名。这个对象放到spring容器中,通过spring容器管理。
    • 把它配置给spring容器,在容器中根据该xml new出对应的对象。
<!-- 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
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="hello1" class="com.qiu.pojo.Hello">
        <property name="name" value="spring"/>
        <!-- ref引用的是一个bean对象 -->
        <property name="h" ref="hello2"/>
    </bean>
    
    <bean id="hello2" class="com.qiu.pojo.Hello">
    </bean>

</beans>
  1. 使用ClassPathXmlApplicationContext类创建一个spring容器
    • 该容器通过beans.xml配置产生,也就是该容器中拥有、管理的是该xml文件中声明的对象。
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello hello = (Hello) context.getBean("hello1");
System.out.println(hello.toString());

这就叫控制反转:传统的程序对象是由程序显式new出来的,使用spring后对象是通过配置xml文件使用spring容器get出来的。控制权交到了用户手里,通过修改xml文件就可以修改业务,不需要修改整个系统代码。

传统程序对象是程序本身的所以程序高度依赖于特定的对象,如果换了业务整个系统的对象代码都需要改变,这就是高耦合的体现!现在通过spring容器进行对象的管理,spring相当于程序与对象之间的一个桥梁,这样换对象对程序影响极小。这就是解耦合的体现!

IOC创建对象的方式

IOC容器中自动创建对象,对象的创建时机在加载xml文件的时候就已经做了。创建对象时调用的bean的无参构造来创建对象。

使用有参构造创建Bean

使用构造器标签constructor-arg(在给属性赋值的时候使用的是property标签,给属性赋值时调用的无参构造)也就是说选择一种:使用property就是调用无参,set进行赋值;使用constructor-arg就是调用有参构造创建对象。

class User{
    private String name;
    private Child child;
    public User{}
    public User(String name, Child child){
        this.name = name;
        this.child = child;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Child getChild() {
        return child;
    }
    public void setChild(Child child) {
        this.child = child;
    }
}
  1. 使用下标进行有参构造赋值
<beans>
    <bean id="child" class="com.qiu.pojo.Child"></bean>
    
    <!-- 使用下标进行有参构造 -->
	<bean id="user" class="com.qiu.pojo.User">
    	<constructor-arg index="0" value="useruser"/>
        <constructor-arg index="1" ref="child"/>
    </bean>
</beans>
  1. 按照类型进行有参构造的赋值

不建议使用!如果构造方法有多个参数值类型相同的参数那么就不能识别了!

<beans>
    <bean id="child" class="com.qiu.pojo.Child"></bean>
    
    <!-- 使用下标进行有参构造 -->
	<bean id="user" class="com.qiu.pojo.User">
    	<constructor-arg type="java.lang.String" value="useruser"/>
        <constructor-arg type="com.qiu.pojo.Child" ref="child"/>
    </bean>
</beans>
  1. 通过参数名进行有参构造的赋值
<beans>
    <bean id="child1" class="com.qiu.pojo.Child"></bean>
    
    <!-- 使用下标进行有参构造 -->
	<bean id="user" class="com.qiu.pojo.User">
    	<constructor-arg name="name" value="useruser"/>
        <constructor-arg name="child" ref="child1"/>
    </bean>
</beans>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值