Spring基本了解以及方法

简介: Spring基本了解以及方法

一.简介

1.1.背景

Spring是一个开源框架,提供了一种全面的、一致的编程模型,用于构建企业级Java应用程序。它能够帮助开发者快速构建可扩展和易于维护的应用程序,并提供了丰富的功能库和工具,以支持各种企业级应用开发需求。


Spring框架最初由Rod Johnson于2003年创建,目的是简化企业级Java开发,并引入了面向切面编程(AOP)的概念。Spring的核心特性包括依赖注入(DI)和控制反转(IoC),它们使开发者能够更灵活地管理和配置应用程序的组件。


Spring框架提供了许多模块和扩展,每个模块都专注于不同的方面,例如Web应用程序开发、数据访问、安全性、消息传递等等。这些模块可以根据项目需求进行选择和集成,使开发人员能够轻松构建各种类型的应用程序。


  目的:解决企业应用开发的复杂性


  功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能


  范围:任何Java应用


  简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

1.2.Spring框架的核心

  1. 依赖注入(Dependency Injection,DI):DI是Spring框架的核心概念之一。它通过将对象之间的依赖关系交给容器管理,从而降低了组件之间的耦合度。开发者只需要定义好对象的依赖关系,而不需要关心如何获取依赖,这使得代码更具灵活性和可测试性。
  2. 控制反转(Inversion of Control,IoC):IoC是DI的实现方式,它实现了反转了对象的控制权。在Spring框架中,应用程序的控制权被转移到了Spring容器中,容器负责创建和管理对象的生命周期,开发者只需要关注业务逻辑的实现。
  3. AOP(面向切面编程):AOP是Spring框架的另一个核心概念。它通过将跨越多个组件的关注点(如日志记录、事务管理等)从业务逻辑中解耦出来,提供了一种非侵入式的方式来增强应用程序的功能。Spring框架提供了AOP的实现,开发者可以通过配置或注解来定义切面和通知,将横切关注点应用于应用程序中的方法或类。
  4. Spring容器(ApplicationContext):Spring容器是Spring框架的核心容器,负责创建和管理对象的生命周期。它通过读取配置文件或基于注解来实例化和组装对象,并提供了依赖注入和控制反转的支持。Spring容器提供了多种不同类型的容器,如ClasspathXmlApplicationContext、AnnotationConfigApplicationContext等,可以根据项目需求选择合适的容器。

二.Spring ioc的容器的特点

2.1.ioc的理解

  • IoC(Inversion of Control)是Spring框架的核心概念之一,也被称为控制反转。它是一种设计原则,用于解耦应用程序中的组件关系,使得代码更加灵活、可扩展、可测试和可维护。
  • Spring中的IoC是通过Spring容器实现的。Spring容器负责实例化和组装对象,它会读取配置文件或基于注解来识别和创建对象,同时自动处理对象之间的依赖关系。开发者只需要通过注解或XML配置文件来描述对象之间的关系,Spring框架会根据配置信息对对象进行实例化和注入。
  • 通过IoC,开发者可以实现松耦合的组件设计,使得代码更具可维护性和可扩展性。同时,IoC也为AOP(面向切面编程)提供了基础,使得开发者可以更容易地在应用程序中实现横切关注点的功能,如日志、事务管理等。

2.2.ioc的特点

实例化对象的权力由程序员转变为Spring IoC容器。

2.3.ioc的优势

  1. 解耦:组件之间的耦合度降低,使得代码更易于理解、扩展和维护。
  2. 可测试性:通过依赖注入可以轻松替换依赖对象,使单元测试更容易实现。
  3. 灵活性:可以在运行时动态修改依赖关系,而不需要修改代码。
  4. 可重用性:组件的逻辑和依赖可以被多个应用重复使用。

2.4.案例演示

在进行案例演示前我们需要进行项目对象模型的配置,如下:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>testspring</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>testspring Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
  <properties>
    <spring.version>5.0.1.RELEASE</spring.version>
    <javax.servlet.version>4.0.0</javax.servlet.version>
    <junit.version>4.12</junit.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!-- 2、导入spring依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- 5.1、junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <!-- 5.2、servlet -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>${javax.servlet.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>testspring</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

UserService接口:

package com.junlinyi.ioc.service;
/**
 * @author JunLinYi
 * @site www.JunLinYi.com
 * @company 君氏集团
 * @create 2023-08-15-14:50
 *
 * 用户更改个人信息的接口
 */
public interface UserService {
    public void update();
}

UserServiceImpl1:

package com.junlinyi.ioc.service.impl;
import com.junlinyi.ioc.service.UserService;
/**
 * @author JunLinYi
 * @site www.junlinyi.com
 * @company 君氏集团
 * @create 2023-08-15-14:52
 *
 * 客户的需求
 * 需求:客户在登录后需要具备更改个人信息的功能
 *
 * 场景1:
 * 客户要求,在新增的需求上做迭代版本,如上传头像
 *
 * 场景2:
 * ...
 * 客户要求,在新增的需求上做优化,提升性能,如使用多线程
 */
public class UserServiceImpl1 implements UserService {
    public void update() {
        System.out.println("更改个人用户信息(普通用户功能)");
        //添加上传头像功能的代码
//        System.out.println("上传头像的功能");
    }
}

UserServiceImpl2:

package com.junlinyi.ioc.service.impl;
import com.junlinyi.ioc.service.UserService;
/**
 * @author JunLinYi
 * @site www.JunLinYi.com
 * @company 君氏集团
 * @create 2023-08-15-14:52
 *
 * 客户的需求
 * 需求:客户在登录后需要具备更改个人信息的功能
 *
 * 场景1:
 * 客户要求,在新增的需求上做迭代版本,如上传头像
 *
 * 场景2:
 * ...
 * 客户要求,在新增的需求上做优化,提升性能,如使用多线程
 */
public class UserServiceImpl2 implements UserService {
    public void update() {
        System.out.println("更改个人用户信息(普通用户功能)");
        //添加上传头像功能的代码
        System.out.println("上传头像的功能(会员用户功能)");
    }
}

UserAction:

package com.junlinyi.ioc.web;
import com.junlinyi.ioc.service.UserService;
/**
 * @author JunLinYi
 * @site www.JunLinYi.com
 * @company 君氏集团
 * @create 2023-08-15-15:04
 *
 * 程序员手动实例化对象的弊端:
 * 1.一旦依赖的接口的实现需要大批量改动,迭代,维护的成本极高
 * 2.当接口的实现类不同时,维护的成本高
 */
public class UserAction {
    private UserService userService;
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public String updata(){
        userService.update();
        return "list";
    }
}

GoodsAction:

package com.junlinyi.ioc.web;
import com.junlinyi.ioc.service.UserService;
/**
 * @author JunLinYi
 * @site www.JunLinYi.com
 * @company 君氏集团
 * @create 2023-08-15-15:09
 */
public class GoodsAction {
    private UserService userService;
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public String updata(){
        userService.update();
        return "list";
    }
}

spring-context.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">
<!--    凡是在Spring配置文件spring-context.xml中配置,那么该类javabean就交给了Spring容器管理-->
    <bean class="com.junlinyi.ioc.web.UserAction" id="userAction">
        <property name="userService" ref="userService"></property>
    </bean>
    <bean class="com.junlinyi.ioc.web.GoodsAction" id="goodsAction">
        <property name="userService" ref="userServiceImpl1"></property>
    </bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

Demo1测试类:

package com.junlinyi.ioc.demo;
import com.junlinyi.ioc.web.GoodsAction;
import com.junlinyi.ioc.web.UserAction;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author JunLinYi
 * @site www.JunLinYi.com
 * @company 君氏集团
 * @create 2023-08-15-15:42
 */
public class Demo1 {
    public static void main(String[] args) {
        //加载Spring核心配置文件(建模),获取Spring的上下文对象,上下文对象中可以获取任何javabean对象
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
        UserAction userAction = (UserAction) context.getBean("userAction");
        userAction.updata();
        System.out.println("********************");
        GoodsAction goodsAction = (GoodsAction) context.getBean("goodsAction");
        goodsAction.updata();
    }
}

演示效果:

三.Spring的注入方式

3.1.set注入

将GoodsAction中的所有代码修改为以下代码:

package com.junlinyi.ioc.web;
import com.junlinyi.ioc.service.UserService;
import java.util.List;
/**
 * @author JunLinYi
 * @site www.JunLinYi.com
 * @company 君氏集团
 * @create 2023-08-15-15:09
 */
public class GoodsAction {
    /**
     * 例如:在不同的控制器中进行方法调用
     */
    private UserService userService;
    private String gname;//名称
    private int age;//保质期
    private List<String> peoples;//使用人群
    public String getGname() {
        return gname;
    }
    public void setGname(String gname) {
        this.gname = gname;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public List<String> getPeoples() {
        return peoples;
    }
    public void setPeoples(List<String> peoples) {
        this.peoples = peoples;
    }
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public void pop(){
        System.out.println("名称:"+this.gname);
        System.out.println("保证期:"+this.age);
        System.out.println("使用人群:"+this.peoples);
    }
    public String update(){
        userService.update();
        return "list";
    }
}

再修改spring-context.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">
<!--    凡是在Spring配置文件spring-context.xml中配置,那么该类javabean就交给了Spring容器管理-->
    <bean class="com.junlinyi.ioc.web.UserAction" id="userAction">
        <property name="userService" ref="userService"></property>
    </bean>
    <bean class="com.junlinyi.ioc.web.GoodsAction" id="goodsAction">
        <property name="userService" ref="userServiceImpl1"></property>
        <property name="gname" value="小文"></property>
        <property name="age" value="19"></property>
        <property name="peoples">
            <list>
                 <value>印度飞饼</value>
                <value>意大利炮</value>
                <value>北京烤鸭</value>
                <value>墨西哥卷</value>
            </list>
        </property>
    </bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

最后返回demo测试类执行结果,如下:

3.2.构造注入

将User Action中的代码修改成以下代码:

package com.junlinyi.ioc.web;
import com.junlinyi.ioc.service.UserService;
import java.util.List;
/**
 * @author JunLinYi
 * @site www.JunLinYi.com
 * @company 君氏集团
 * @create 2023-08-15-15:04
 *
 * 程序员手动实例化对象的弊端:
 * 1.一旦依赖的接口的实现需要大批量改动,迭代,维护的成本极高
 * 2.当接口的实现类不同时,维护的成本高
 */
public class UserAction {
    private UserService userService ;
    private  String uname;//姓名
    private  int age;//年龄
    private List<String> hobby;//爱好
    public UserAction() {
    }
    public UserAction(String uname, int age, List<String> hobby) {
        this.uname = uname;
        this.age = age;
        this.hobby = hobby;
    }
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public void pop(){
        System.out.println("名字为:"+this.uname);
        System.out.println("年龄为:"+this.age);
        System.out.println("爱好为:"+this.hobby);
    }
    public String updata(){
        userService.update();
        return "list";
    }
}

再修改spring-context.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">
<!--    凡是在Spring配置文件spring-context.xml中配置,那么该类javabean就交给了Spring容器管理-->
    <bean class="com.junlinyi.ioc.web.UserAction" id="userAction">
        <property name="userService" ref="userService"></property>
        <constructor-arg name="uname" value="扎克" ></constructor-arg>
        <constructor-arg name="age" value="18" ></constructor-arg>
        <constructor-arg name="hobby">
        <list>
            <value>唱,跳</value>
            <value>Rap</value>
            <value>篮球</value>
        </list>
        </constructor-arg>
    </bean>
    <bean class="com.junlinyi.ioc.web.GoodsAction" id="goodsAction">
        <property name="userService" ref="userServiceImpl1"></property>
        <property name="gname" value="小文"></property>
        <property name="age" value="19"></property>
        <property name="peoples">
            <list>
                <value>印度飞饼</value>
                <value>意大利炮</value>
                <value>北京烤鸭</value>
                <value>墨西哥卷</value>
            </list>
        </property>
    </bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

最后返回demo测试类执行结果,结果如下:

3.3.接口注入

自动装配:byName byType

byName:javaBean会根据属性名在spring的上下文中的bean的id进行查找,只要有就会自动装配

修改spring-context..xml配置文件,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       default-autowire="byName"
       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">
<!--    凡是在Spring配置文件spring-context.xml中配置,那么该类javabean就交给了Spring容器管理-->
    <bean class="com.junlinhyi.ioc.web.UserAction" id="userAction">
        <property name="userService" ref="userService"></property>
<!--        <constructor-arg name="uname" value="扎克" ></constructor-arg>-->
<!--        <constructor-arg name="age" value="18" ></constructor-arg>-->
<!--        <constructor-arg name="hobby">-->
<!--        <list>-->
<!--            <value>唱,跳</value>-->
<!--            <value>Rap</value>-->
<!--            <value>篮球</value>-->
<!--        </list>-->
<!--        </constructor-arg>-->
    </bean>
    <bean class="com.junlinhyi.ioc.web.GoodsAction" id="goodsAction">
        <property name="userService" ref="userServiceImpl1"></property>
<!--        <property name="gname" value="小文"></property>-->
<!--        <property name="age" value="19"></property>-->
<!--        <property name="peoples">-->
<!--            <list>-->
<!--                <value>印度飞饼</value>-->
<!--                <value>意大利炮</value>-->
<!--                <value>北京烤鸭</value>-->
<!--                <value>墨西哥卷</value>-->
<!--            </list>-->
<!--        </property>-->
    </bean>
    <bean class="com.junlinhyi.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.junlinhyi.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

测试结果:


注:如果名称不同或者没有改名称将会有空指针报错(null值报错)

byType:JavaBean会议根据属性名对应的接口,在spring上下文中进行查找

查找方式:是根据spring上下文中是否有接口实现类进行匹配,只要有就自动配置。

修改spring-context.xml 配置文件,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       default-autowire="byType"
       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">
<!--    凡是在Spring配置文件spring-context.xml中配置,那么该类javabean就交给了Spring容器管理-->
    <bean class="com.junlinyi.ioc.web.UserAction" id="userAction">
        <property name="userService" ref="userService"></property>
<!--        <constructor-arg name="uname" value="扎克" ></constructor-arg>-->
<!--        <constructor-arg name="age" value="18" ></constructor-arg>-->
<!--        <constructor-arg name="hobby">-->
<!--        <list>-->
<!--            <value>唱,跳</value>-->
<!--            <value>Rap</value>-->
<!--            <value>篮球</value>-->
<!--        </list>-->
<!--        </constructor-arg>-->
    </bean>
    <bean class="com.junlinyi.ioc.web.GoodsAction" id="goodsAction">
        <property name="userService" ref="userServiceImpl1"></property>
<!--        <property name="gname" value="小文"></property>-->
<!--        <property name="age" value="19"></property>-->
<!--        <property name="peoples">-->
<!--            <list>-->
<!--                <value>印度飞饼</value>-->
<!--                <value>意大利炮</value>-->
<!--                <value>北京烤鸭</value>-->
<!--                <value>墨西哥卷</value>-->
<!--            </list>-->
<!--        </property>-->
    </bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.junlinyi.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

结果为:

注:如果没有或者有两个以上的接口实现类将会报错,因为是自动查询如有多个将不知道是哪个。


最后ISpring之IoC容器篇就到这里,祝大家在敲代码的路上一路通畅!

感谢大家的观看 !

目录
相关文章
|
20天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
28 1
|
25天前
|
存储 安全 Java
|
21天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
25 1
|
17天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
21 0
|
2月前
|
Java 应用服务中间件 Spring
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
|
4月前
|
安全 Java Spring
Spring问题之如何配置Bean的初始化方法和销毁方法
Spring问题之如何配置Bean的初始化方法和销毁方法
|
3月前
|
Java Spring
|
3月前
|
存储 SQL Java
|
4月前
|
Java Spring
Spring初始化加速的思路和方案问题之在BeanFactory#doGetBean方法中,栈状态的变化影响bean的初始化的问题如何解决
Spring初始化加速的思路和方案问题之在BeanFactory#doGetBean方法中,栈状态的变化影响bean的初始化的问题如何解决
|
4月前
|
Java 数据库连接 API
Spring事务管理嵌套事务详解 : 同一个类中,一个方法调用另外一个有事务的方法
Spring事务管理嵌套事务详解 : 同一个类中,一个方法调用另外一个有事务的方法
266 1