Spring之IoC容器篇

news2024/11/15 15:36:44

目录

1.Spring简介

1.1Spring框架的核心特性

2.Spring IoC容器

2.1Spring IoC容器特点

2.2出现的背景

2.3关于IoC的理解

2.4案例演示

3.Spring注入方式

3.1set注入

3.2构造注入

3.3接口注入

4.Spring上下文与tomcat整合

4.1思考

4.2代码演示

4.3收获


1.Spring简介

Spring是一个开源的应用程序开发框架,它由Rod Johnson创建,主要用于构建企业级Java应用程序。它提供了一个全面的编程和配置模型,可以简化Java开发过程,提高开发效率和可维护性。即为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。

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

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

   范围:任何Java应用

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

1.1Spring框架的核心特性

Spring框架的核心特性包括:

  1. IoC容器:Spring的IoC(Inversi      on of Control)容器管理对象的生命周期和依赖关系,通过依赖注入(DI)将对象的依赖关系外部化,降低了组件之间的耦合度,增强了代码的可测试性。

  2. AOP支持:Spring提供了强大的面向切面编程(AOP)支持,可以实现横切关注点的模块化,例如日志记录、事务管理等功能,将它们与业务逻辑分离。

  3. 数据访问抽象层:Spring提供了包括JDBC、ORM(如Hibernate、MyBatis)等在内的数据访问抽象层,简化了数据库操作的编码工作,并提供了一致的异常处理机制。

  4. MVC框架:Spring MVC是一个基于模型-视图-控制器模式的Web应用程序框架,用于构建灵活而功能强大的Web应用程序。它与Spring框架紧密集成,可以方便地进行请求处理、表单验证、视图渲染等等。

  5. 安全性:Spring提供了安全性模块,支持基于角色的访问控制和认证。

  6. 容器扩展:Spring框架可以通过扩展点和插件机制进行定制和扩展,以满足特定业务需求。

2.Spring IoC容器

2.1Spring IoC容器特点

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

2.2出现的背景

IoC(Inversion of Control)出现的背景可以追溯到软件开发领域中的耦合和复杂性问题。

在传统的软件开发中,对象之间的依赖关系通常是硬编码在代码中的,对象之间直接进行创建和调用。这种紧耦合的设计导致了代码的复杂性和可维护性的下降。当需要修改某个对象的依赖关系时,必须修改代码并重新编译整个应用程序,这样显著增加了开发和维护的成本。

为了解决这些问题,IoC的概念逐渐被引入。

2.3关于IoC的理解

  • 控制反转(IoC):将实例化对象的权力,由程序员控制转交给Spring容器来控制(权力的转交被称为反转)。
  • 本质:IoC的本质是控制对象的创建和依赖关系的权力由调用者转移到了外部容器,也就是所谓的控制反转。它通过将对象的创建、初始化和依赖关系的管理交给容器来实现。
  • 出现的原因:IoC的出现主要是为了解决传统软件开发中的耦合和复杂性问题,通过将对象的创建和依赖管理交给容器来实现控制反转,从而提高代码的模块化、可维护性和可测试性。 

它通过将对象的创建、初始化和依赖关系的管理交给容器来实现。调用者只需要声明需要哪些对象和依赖,而无需关心对象的创建过程和依赖关系的维护。这种松散的耦合使得代码更加模块化、可扩展和易于测试。

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.kissship.ioc.service;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @create 2023-08-15-14:50
 *
 * 用户更改个人信息的接口
 */
public interface UserService {
    public void update();
}

UserServiceImpl1:

package com.kissship.ioc.service.impl;

import com.kissship.ioc.service.UserService;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @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.kissship.ioc.service.impl;

import com.kissship.ioc.service.UserService;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @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.kissship.ioc.web;

import com.kissship.ioc.service.UserService;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @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.kissship.ioc.web;

import com.kissship.ioc.service.UserService;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @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.kissship.ioc.web.UserAction" id="userAction">
        <property name="userService" ref="userService"></property>
    </bean>
    <bean class="com.kissship.ioc.web.GoodsAction" id="goodsAction">
        <property name="userService" ref="userServiceImpl1"></property>
    </bean>
    <bean class="com.kissship.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.kissship.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

Demo1测试类:

package com.kissship.ioc.demo;

import com.kissship.ioc.web.GoodsAction;
import com.kissship.ioc.web.UserAction;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @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();
    }
}

演示效果:

3.Spring注入方式

3.1set注入

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

package com.kissship.ioc.web;

import com.kissship.ioc.service.UserService;

import java.util.List;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @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.kissship.ioc.web.UserAction" id="userAction">
        <property name="userService" ref="userService"></property>
    </bean>
    <bean class="com.kissship.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.kissship.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.kissship.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

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

 

3.2构造注入

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

package com.kissship.ioc.web;

import com.kissship.ioc.service.UserService;

import java.util.List;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @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.kissship.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.kissship.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.kissship.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.kissship.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.kissship.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.kissship.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.kissship.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.kissship.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.kissship.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.kissship.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.kissship.ioc.service.impl.UserServiceImpl2" id="userService"></bean>
    <bean class="com.kissship.ioc.service.impl.UserServiceImpl1" id="userServiceImpl1"></bean>
</beans>

测试结果:

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

4.Spring上下文与tomcat整合

4.1思考

  1. 现在是每一个请求都建模一次,非常消耗性能。
  2. 希望只进行一次建模,然后每个请求都要可以获取到spring上下文。
  3. 那就是 监听器 ,将spring上下文放入tomcat上下文中

4.2代码演示

创建一个监听器SpringLoadListener,如下:

package com.kissship.ioc.listener;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.annotation.WebListener;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @create 2023-08-16-23:54
 */
@WebListener
public class SpringLoadListener implements ServletContextAttributeListener {
    //将spring上下文放入tomcat上下文中。

    public void contextInitialized(ServletContextEvent sce) {
        //加载spring核心配置文件(建模),获取spring上下文对象及上下文对象中可以获取任何javabean的对象
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
        //获取tomcat上下文
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("springContext", context);
    }
}

然后我们需要在测试前创建一个UserServlet进行访问,如下:

package com.kissship.ioc.web;

import com.kissship.ioc.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Kissship
 * @site www.Kissship.com
 * @company xxx公司
 * @create 2023-08-16-23:59
 */
@WebServlet("/userList")
public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springContext");

        UserService userService = (UserService) context.getBean("userService");
        System.out.println(userService);
        userService.update();
    }
}

然后进行重启tomcat进行请求测试就行了。

4.3收获

学习Spring框架后,你将获得以下几方面的收获:

1. 简化开发流程:Spring框架提供了丰富的开发工具和模块,帮助你简化企业级应用程序的开发过程。通过使用Spring的IoC容器和注解,你可以将应用程序的对象的创建和配置工作交给框架处理,从而简化了开发过程,减少了冗余的代码。
2. 提高开发效率:Spring框架提供了很多现成的功能模块,如数据访问、事务管理、安全性支持等,可以减少开发人员手动编写这些功能模块的工作量。你可以通过配置或注解的方式快速集成这些功能,从而提高了开发效率。
3. 松耦合的设计:通过IoC容器和依赖注入,Spring框架实现了对象之间的松耦合。你可以更加专注于业务逻辑的实现,而不用过多关注对象之间的依赖关系。这种松耦合的设计使得应用程序更加灵活、可扩展和易于维护。
4. 更好的可测试性:Spring框架的设计理念使得应用程序的各个组件可以更容易地进行单元测试和集成测试。通过依赖注入,你可以轻松地模拟各个组件的依赖关系,从而更方便地编写测试代码,并保证应用程序的质量。
5. AOP的应用:Spring框架提供了全面的AOP支持,使你能够将与核心业务逻辑无关的功能模块(如事务管理、日志记录、缓存等)以切面的方式进行统一管理。这种模块化的设计能够提高代码的重用性和可维护性。
6. 更好的代码组织和可维护性:通过使用Spring框架,你可以将应用程序的不同层次的代码(如控制层、业务逻辑层、数据访问层)更好地组织起来,实现代码的分层和模块化。这种组织方式使得代码更具可读性、可维护性,方便团队协作开发。


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

感谢大家的观看 !

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/907867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【内网监控】通过cpolar实现远程监控

【内网监控】通过cpolar实现远程监控 文章目录 【内网监控】通过cpolar实现远程监控前言1. 在cpolar官网预留一个空白隧道2. 完成空白数据隧道&#xff0c;生成地址3. 设置空白隧道的出口4. 空白数据隧道的出口设置5. 获取公网地址6. 打开本地电脑“远程桌面”7. 打开Windows自…

AMBA总线协议(4)——AHB(二)

目录 一、前言 二、AHB操作概述 三、AHB 基本传输 1、简单传输 2、带有等待的传输 3、多重传输 四、AHB传输类型 五、小结 一、前言 在之前的文章中对于AMBA AHB做了一个简单的介绍&#xff0c;AHB 主要用于高性能模块(如 CPU、DMA 和 DSP 等)之间的连接&#x…

【工具使用】Keil5软件使用-进阶调试篇

一、概述 本文面向已经懂得软件基本操作的职业老手&#xff0c;如果是未使用过该软件的小鲜肉&#xff0c;请移步基础篇。这里以STM32芯片为例对工具进行讲解&#xff0c;其他品牌的芯片在调试方面上可能存在差异。 二、软件说明 Keil提供了包括C编译器、宏汇编、链接器、库管…

内核日志过滤

本操作以centos为例。 1、不想把日志存入到 /var/log/messages中&#xff0c;转存到其他文件 >1.1、修改配置文件 /etc/rsyslog.conf vim /etc/rsyslog.conf# 添加以下代码if $programname kernel and ($msg contains hexdump or $msg contains shentong_data_file) then …

如祺出行递表,港交所迎来首位Robotaxi商业化观察对象

港交所近年来持续对新经济公司和科技创新类公司释放善意&#xff0c;接连优化上市条款&#xff0c;摆出“筑巢引凤”姿态。这也让外界对新兴领域的兴趣大大增加。 8月18日&#xff0c;出行科技与服务公司如祺出行正式递表港交所&#xff0c;其业务模式为Robotaxi和有人驾驶网约…

python AI绘图教程

前提 1.安装python 2.安装git 步骤 下载stable-diffusion-webui项目&#xff08;链接&#xff1a;GitHub - AUTOMATIC1111/stable-diffusion-webui: Stable Diffusion web UI&#xff09; git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git 安装st…

git管理代码

理论上改代码前要pull一次&#xff0c;然后在push前在pull一次 改代码前pull一次是为了获取最新的同步&#xff0c;但是coding也是需要时间的&#xff0c;难保敲代码的这段时间没有人动远程仓库的东西&#xff0c;所以在改完代码要push的时候也应该再pull一下看有无冲突&#x…

《Zookeeper》源码分析(十七)之 LeaderZooKeeperServer

目录 LeaderZooKeeperServer类结构创建LeaderZooKeeperServer加载初始化数据loadData()启动LeaderZooKeeperServersetupRequestProcessors() LeaderZooKeeperServer 类结构 ZooKeeperServer主要是设置了一系列Processor处理器&#xff0c;对于不同的服务器角色有不同的实例类…

论文导读 | Operations Research近期文章精选

推文作者&#xff1a;张曦予 编者按 本期我们选取了七月后半月来自Operations Research的一篇文章以及来自Management Science的四篇文章以飨读者&#xff0c;内容涉及多个方面&#xff0c;我们选取的文章包含了各个方面对于管理以及运筹进行研究的文章&#xff0c;如研究疲劳对…

更新清华软件源时报错:Certificate verification failed: The certificate is NOT trusted.

场景&#xff1a; 在下载libapriltag-dev依赖时&#xff0c;Linux给报了一个错误&#xff1a;E: Unable to locate package libapriltag-dev 。这个错误经常会出现&#xff0c;无法在现有的软件源里找到该安装包或者该依赖&#xff0c;这个时候&#xff0c;首先我们就需要先检查…

服务运营 | MSOR文章精选:远程医疗服务中的统计与运筹(一)

推文作者&#xff1a;蔡君洋&#xff0c;Guo 编者按 《哈佛商业评论》在今年1月20日发表了《是时候巩固远程医疗在美国医疗保健中的地位了&#xff08;It’s Time to Cement Telehealth’s Place in U.S. Health Care&#xff09;》一文。文章指出&#xff0c;在COVID-19大流行…

4.SpringCloud 基本架构

1.SpringCloud概述 Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具&#xff08;例如配置管理&#xff0c;服务发现&#xff0c;断路器&#xff0c;智能路由&#xff0c;微代理&#xff0c;控制总线&#xff0c;一次性令牌&#xff0c;全局锁&#xff0c;…

设置前端项目站标 favicon.ico

1、首先我们需要准备一个小图标利用在线ico工具制作 .ico 的文件 在线工具favicon制作 - 在线工具favicon在线制作,icon制作,网站图标,网站图标制作,ico图标制作https://tool.lu/favicon/选择自己想要制作的小图标&#xff0c;然后选择48*48的下载就可以了 将下载的文件名改为f…

leetcode 123. 买卖股票的最佳时机 III

2023.8.21 本题限制了买卖次数&#xff1a;最多买卖两次。 与之前的股票问题相比&#xff0c;dp数组的第二个维度需要设置四个状态&#xff1a; 第一次持有股票第一次不持有股票第二次持有股票第二次不持有股票 ps&#xff1a;持有股票不等于购买股票&#xff01;&#xff01…

【Git版本控制工具使用---讲解一】

Git版本控制工具使用 安装设置用户名签名和邮箱Git常用的命令 初始化本地库查看本地状态Git 命令添加暂存区提交本地库查看版本信息修改文件版本穿梭 安装 首先根据自身电脑的配置选择性的安装是32位的还是64位的Git版本控制工具 我这边安装的是64位的 以下是我安装的时候的过…

jmeter HTTP信息头管理器

首先&#xff0c;打开JMeter并创建一个新的测试计划。右键单击测试计划&#xff0c;选择"添加" > “线程组”&#xff0c;然后在线程组上右键单击&#xff0c;选择"添加" > “Sampler” > “HTTP请求”。 在HTTP请求中填写服务器的URL和其他必要…

深入浅出带你玩转栈与队列——【数据结构】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 目录 1.栈 1.1栈的概念及结构 1.2栈的结构特征图 ​编辑 1.3栈的实现 1.3.1栈的初始化 1.3.2进栈 1.3.3出栈 1.3.4销毁内存 1.3.5判断栈是否为空 1.3.5栈底元素的读取 1.3.6栈中大小 1.4栈实现所有接口 2…

时序预测 | MATLAB实现SO-CNN-BiLSTM蛇群算法优化卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现SO-CNN-BiLSTM蛇群算法优化卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现SO-CNN-BiLSTM蛇群算法优化卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 | MATLAB实现SO-CNN-BiL…

增强数字风险防护管理,天际友盟牵头正式发布GDN·全球数字风险阻断网络

随着数字化进程的加快&#xff0c;企业对于数字风险防护管理的需求与日俱增&#xff0c;其数字足迹、数字资产&#xff0c;甚至高管的个人形象都可能成为不法分子的攻击目标。保护关键数字资产与数据免受外部威胁&#xff0c;提升在线业务运营稳健性的价值毋庸置疑。 8月18日&a…

QQ音乐刷时长和音响力工具-无需密码

QQ音乐刷等级是一款安卓端的QQ音乐刷时长和音响力工具&#xff0c;使用时无需密码登录&#xff0c;直接输入qq号码即可&#xff0c;支持微信账号&#xff0c;每提交一次可以刷99分钟的听歌时长&#xff0c;实时到账&#xff0c;刷的听歌时长可以增加听歌排行榜跟音响力(就是QQ音…