Java学习路线-56:Spring与Ioc

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Java学习路线-56:Spring与Ioc

Spring

官网:https://spring.io/

理念:使现有技术更加实用,本身是大杂烩整合现有的框架技术

优点:

  1. 轻量级框架
  2. Ioc 容器-控制反转 inversion of Control
  3. Aop 面向切面编程
  4. 对事务支持
  5. 对框架的支持

一、Ioc 控制反转

Ioc 是一种编程思想,由主动编程变为被动接收

别名:依赖注入 dependency injection

控制:

指谁来控制对象的创建

传统的应用程序对象的创建是由程序本身控制的

使用 spring 之后,由 spring 创建对象


反转:

正转指程序来创建对象

反转指程序本身不创建对象,而变成被动接受对象


总结:

以前对象是由程序本身创建,

使用 spring 之后,程序变为接收 spring 创建好的对象

简单示例

1、依赖 pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>

2、Person.java

package com.pengshiyu.bean;
public class Person {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}

3、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 name="person" class="com.pengshiyu.bean.Person">
        <property name="name" value="张三" />
    </bean>
</beans>

4、Demo.java

package com.pengshiyu.spring;
import com.pengshiyu.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
    public static void main(String[] args) {
        // 解析beans.xml 文件,生成对应的Bean对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person)context.getBean("person");
        person.sayHello();
    }
}

二、Dao 管理示例

Ioc: 对象由 spring 来创建

1、UserDao

package com.spring.dao;
public interface UserDao {
    public void getUser();
}

2、UserDaoMysqlImpl

package com.spring.dao.impl;
import com.spring.dao.UserDao;
public class UserDaoMysqlImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("Mysql 获取用户信息");
    }
}

3、UserDaoOracleImpl

package com.spring.dao.impl;
import com.spring.dao.UserDao;
public class UserDaoOracleImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("Oracle 获取用户信息");
    }
}

4、UserService

package com.spring.service;
public interface UserService {
    public void getUser();
}

5、UserServiceImpl

package com.spring.service.impl;
import com.spring.dao.UserDao;
import com.spring.service.UserService;
public class UserServiceImpl implements UserService {
    private UserDao userDao = null;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        this.userDao.getUser();
    }
}

6、beans.xml(简化版)

<beans >
    <bean id="mysqlDao" class="com.spring.dao.impl.UserDaoMysqlImpl" />
    <bean id="oracleDao" class="com.spring.dao.impl.UserDaoOracleImpl" />
    <bean id="service" class="com.spring.service.impl.UserServiceImpl">
        <property name="userDao" ref="mysqlDao"></property>
    </bean>
</beans>

7、TestDemo

package com.spring.test;
import com.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDemo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService service = (UserService)context.getBean("service");
        service.getUser();
    }
}

三、使用 Ioc 来创建对象的 3 种方法

Person 类

package com.pengshiyu.bean;
public class Person {
    private String name;
    public Person() {
    }
    public Person(String name) {
        this.name = name;
    }
    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}

创建对象

package com.spring.test;
import com.pengshiyu.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person) context.getBean("person");
        person.sayHello();
    }
}

beans.xml(简化版)

1、无参构造

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person" />
</beans>

2、有参构造

(1)根据参数下标设置

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <!-- index 构造方法下标从 0 开始 -->
        <constructor-arg index="0" value="Tom" />
    </bean>
</beans>

(2)根据参数名称设置

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <!-- name 参数名-->
        <constructor-arg name="name" value="Tom" />
    </bean>
</beans>

3、工厂方法创建

(1)静态工厂

package com.pengshiyu.factory;
import com.pengshiyu.bean.Person;
public class PersonFactory {
    public static Person newInstance(String name) {
        return new Person(name);
    }
}
<beans >
    <bean name="person" class="com.pengshiyu.factory.PersonFactory" factory-method="newInstance">
        <constructor-arg name="name" value="Tom" />
    </bean>
</beans>

(2)动态工厂

package com.pengshiyu.factory;
import com.pengshiyu.bean.Person;
public class PersonFactory {
    public Person newInstance(String name) {
        return new Person(name);
    }
}
<beans>
    <bean id="factory" class="com.pengshiyu.factory.PersonFactory" />
    <bean name="person" factory-bean="factory" factory-method="newInstance">
        <constructor-arg name="name" value="Tom"/>
    </bean>
</beans>

注意静态工厂 static

四、Spring 配置文件

id 是 bean 的唯一标识符,如果没有配置 id,name 默认为标识符

如果配置了 id,又配置了 name,则 name 是别名

name 可以设置多个别名分隔符可以是空格、逗号、分号

class 是 bean 的全限定名=包名+类名

如果不配置 id 和 name,那么可以可以使用如下方式获取对象

applicationContext.getBean(class)

配置如下

<beans >
    <bean id="person1" name="person user" class="com.pengshiyu.bean.Person" />
</beans>

获取方式

Person person = (Person) context.getBean("person1");
// 或者
Person person = (Person) context.getBean("user");
// 或者
Person person = (Person) context.getBean(Person.class);

导入文件

<beans>
    <import resource="person.xml"/>
</beans>

五、Spring 依赖注入 DI

dependency injection

依赖:指 bean 对象创建依赖于容器,bean 对象的依赖资源

注入:指 bean 对象依赖的资源由容器来设置和装配

spring 注入

测试

package com.spring.test;
import com.pengshiyu.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person) context.getBean("person");
        person.sayHello();
    }
}
  1. 构造器注入
package com.pengshiyu.bean;
public class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}
<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <constructor-arg name="name" value="Tom"/>
    </bean>
</beans>
  1. setter 注入

(1)常量注入

package com.pengshiyu.bean;
public class Person {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}
<beans >
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="name" value="Tom"/>
    </bean>
</beans>

(2)bean 注入

package com.pengshiyu.bean;
public class Address {
    private String address;
    public void setAddress(String address) {
        this.address = address;
    }
    public String getAddress() {
        return address;
    }
}
package com.pengshiyu.bean;
public class Person {
    private String name;
    private Address address;
    public void setAddress(Address address) {
        this.address = address;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void sayHello() {
        System.out.println("hello " + this.name + this.address.getAddress());
    }
}
<beans >
    <bean id="address" class="com.pengshiyu.bean.Address">
        <property name="address" value="北京"/>
    </bean>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="name" value="Tom"/>
        <property name="address" ref="address"/>
    </bean>
</beans>

(3)数组注入

package com.pengshiyu.bean;
public class Book {
    private  String name;
    public Book(String name){
        this.name = name;
    }
    @Override
    public String toString() {
        return "《" + this.name + "》";
    }
}
package com.pengshiyu.bean;
import java.util.Arrays;
public class Person {
    private Book[] books;
    public void setBooks(Book[] books) {
        this.books = books;
    }
    @Override
    public String toString() {
        return "Person{" +
                "books=" + Arrays.toString(books) +
                '}';
    }
}
<beans >
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="books">
            <array>
                <value>水浒传</value>
                <value>红楼梦</value>
                <value>三国演义</value>
                <value>西游记</value>
            </array>
        </property>
    </bean>
</beans>

(4)List 注入

package com.pengshiyu.bean;
import java.util.Arrays;
import java.util.List;
public class Person {
    private List<String>[] books;
    public void setBooks(List<String>[] books) {
        this.books = books;
    }
    @Override
    public String toString() {
        return "Person{" +
                "books=" + Arrays.toString(books) +
                '}';
    }
}
<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="books">
            <list>
                <value>水浒传</value>
                <value>红楼梦</value>
                <value>三国演义</value>
                <value>西游记</value>
            </list>
        </property>
    </bean>
</beans>

(5)Map 注入

package com.pengshiyu.bean;
import java.util.Map;
public class Person {
    private Map<String, String> cards;
    public void setCards(Map<String, String> cards) {
        this.cards = cards;
    }
    @Override
    public String toString() {
        return cards.toString();
    }
}
<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="cards">
            <map>
                <entry key="中国银行" value="123456"></entry>
                <entry key="建设银行" value="123456"></entry>
            </map>
        </property>
    </bean>
</beans>

(6)Set 注入

package com.pengshiyu.bean;
import java.util.Set;
public class Person {
    private Set<String> games;
    public void setGames(Set<String> games) {
        this.games = games;
    }
    @Override
    public String toString() {
        return games.toString();
    }
}
<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="games">
            <set>
                <value>英雄联盟</value>
                <value>王者荣耀</value>
            </set>
        </property>
    </bean>
</beans>

(7)null 注入

package com.pengshiyu.bean;
public class Person {
    public void setWife(String wife) {
        this.wife = wife;
    }
    private String wife;
    @Override
    public String toString() {
        return wife;
    }
}
<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="wife"><null/></property>
    </bean>
</beans>

(8) Properties 注入

package com.pengshiyu.bean;
import java.util.Properties;
public class Person {
    private Properties props;
    public void setProps(Properties props) {
        this.props = props;
    }
    @Override
    public String toString() {
        return this.props.toString();
    }
}
<beans >
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="props">
            <props>
                <prop key="name">Tom</prop>
                <prop key="sex">Man</prop>
            </props>
        </property>
    </bean>
</beans>

(9) p 命名空间注入

需要有对应的 set 方法

package com.pengshiyu.bean;
public class Person {
    private String name;
    private int age;
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

头文件需要引入

xmlns:p="http://www.springframework.org/schema/p"
<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="person" class="com.pengshiyu.bean.Person"
          p:name="Tom" p:age="23"/>
</beans>

(10)c 命名空间注入

要求有对应的构造方法

package com.pengshiyu.bean;
public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

头文件需要引入

xmlns:c="http://www.springframework.org/schema/c"
<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="person" class="com.pengshiyu.bean.Person"
          c:name="Tom" c:age="23"/>
</beans>

六、bean 的作用域

spring

桥梁
轻量级
易学
ioc di
app
事务
整合框架

scope:

  1. singleton 单例 整个容器只有一个对象实例(默认)
  2. prototype 原型 每次获取 Bean 都产生一个新对象
  3. request 每次请求时创建一个新的对象
  4. session 会话范围内有一个对象
  5. global session 只在 portlet 下有用,表示 applicatio
  6. application 在应用范围中有一个对象


Bean 自动装配

autowire

  1. byName
  2. byType
  3. constructor

不推荐使用自动装配

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
93 2
|
10天前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
98 69
|
3天前
|
Java Spring
Java Spring Boot监听事件和处理事件
通过上述步骤,我们可以在Java Spring Boot应用中实现事件的发布和监听。事件驱动模型可以帮助我们实现组件间的松耦合,提升系统的可维护性和可扩展性。无论是处理业务逻辑还是系统事件,Spring Boot的事件机制都提供了强大的支持和灵活性。希望本文能为您的开发工作提供实用的指导和帮助。
39 15
|
9天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
40 21
|
15天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
1天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
13天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
65 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
1月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
57 2
|
2月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
57 0