Spring框架入门以及 ioc的三种注入方式

简介: Spring框架入门以及 ioc的三种注入方式

一、Spring是什么,它能够做什么

 Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。

  Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。

  然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

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

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

  范围:任何Java应用,包括Web应用程序、桌面应用程序、批处理应用程序等。

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

spring的组成

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

  1. Spring Core(核心模块):
    提供了IoC容器和依赖注入功能,用于管理对象的生命周期和依赖关系。
  2. Spring Context(上下文模块):
    基于核心模块,提供了更广泛的应用程序上下文支持,包括国际化、事件传播、资源加载等。
  3. Spring AOP(面向切面编程模块):
    提供了AOP功能,用于将横切关注点与业务逻辑分离,实现日志记录、事务管理等功能。
  4. Spring JDBC(数据库访问模块):
    提供了对JDBC的封装和简化,简化了数据库访问的代码编写。
  5. Spring ORM(对象关系映射模块):
    提供了对ORM框架的集成支持,如Hibernate、MyBatis等,简化了数据库操作和对象持久化的开发。
  6. Spring Web(Web开发模块):
    提供了用于构建Web应用程序的功能,包括Spring MVC框架、RESTful Web服务、WebSocket等。
  7. Spring Security(安全性模块):
    提供了一套综合的安全性框架,用于认证、授权和保护应用程序的资源。
  8. Spring Test(测试模块):
    提供了测试支持,包括单元测试、集成测试和端到端测试,方便进行测试驱动开发和持续集成。

控制反转(Inversion of Control,IoC)和依赖注入(Dependency Injection,DI)是两个相关的概念,用于解耦和管理组件之间的依赖关系。

控制反转(IoC)是一种设计原则,它将组件的控制权从组件自身转移到外部容器中。传统的程序设计中,组件通常负责自己的创建和管理,而在IoC中,组件不再负责自己的创建和管理,而是由外部容器来负责。这样做的好处是,组件不再与具体的实现细节紧密耦合,而是通过接口或抽象类与外部容器进行交互,从而提高了代码的可维护性和可测试性。

依赖注入(DI)是IoC的一种具体实现方式。它通过将组件所依赖的其他组件(依赖项)注入到组件中,来解决组件之间的依赖关系。依赖注入可以通过构造函数、属性或方法参数等方式进行。通过依赖注入,组件不需要自己创建和管理它所依赖的组件,而是由外部容器负责创建和注入依赖项。这样可以使组件之间的依赖关系更加清晰和可控,提高了代码的可测试性和可扩展性。

分析实现

首先需建一个maven工程,在pom.xml中导入spring的jar包依赖

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.1.10.RELEASE</version>
</dependency>

给客户添加一个文件上传的接口,实现文件上传的功能

1.建立一个UserBiz接口

public interface UserBiz {
 public void update();
}

2.实现接口完成功能

public class UserBizImpl implements UserBiz {
    public void update() {
        System.out.println("用户功能实现类");
    }
}

3.客户要求更改需求

1. public class UserBizImpl2 implements UserBiz {
2.  
3.     public void update() {
4.             System.out.println("更改用户需求");
5.     }
6.  
7. }

4.编写Userservlet,Goodsservlet

public class UserAction {
    private UserBiz userBiz= new UserBizImpl2();
    public String Update(){
        userBiz.update();
        return "list";
    }
}
public class GoodsAction {
    private UserBiz userBiz= new UserBizImpl2();
    public String Update(){
        userBiz.update();
        return "list";
    }
}

5.新建一个spring的xml,博主在这命名为spring_context

<?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 class="com.ctb.web.UserAction" id="userAction">
        <property name="iub" ref="iub"></property>
    </bean>
    <bean class="com.ctb.web.GoodsAction" id="goodsAction">
        <property name="iub" ref="impl1"></property>
    </bean>
    <bean class="com.ctb.biz.Impl.UserBizImpl2" id="iub"></bean>
    <bean class="com.ctb.biz.Impl.UserBizImpl1" id="impl1"></bean>
</beans>

测试类

package com.ctb.demo;
import com.ctb.web.GoodsAction;
import com.ctb.web.UserAction;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author 彪
 * @remark
 * @create  2023-08-16 21:30
 */
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.upload();
        GoodsAction goodsAction= (GoodsAction) context.getBean("goodsAction");
        goodsAction.upload();
    }
}

三、 如何在spring当中定义和配置一个JavaBean

  • 在Spring中定义JavaBean可以使用XML配置文件或注解。
  • 使用XML配置文件时,可以使用<bean>元素来定义和配置JavaBean,包括类名、属性值、依赖项等。
  • 使用注解时,可以使用@Component@Service@Repository等注解来标记JavaBean,并使用@Autowired注解来实现依赖注入。

四、注入方式

1.构造函数注入

  • 构造函数注入是通过在类的构造函数中传递依赖项来实现的。
  • 在使用构造函数注入时,需要在类中定义一个或多个构造函数,接受依赖项作为参数。
  • Spring容器会根据配置文件或注解中的定义,自动解析依赖项,并在创建对象时将其传递给构造函数。
  • 构造函数注入可以保证对象的依赖项在创建时就被满足,使得对象在创建后具有完整的状态。
package com.ctb.ioc.web;
import com.ctb.ioc.service.UserService;
import java.util.List;
public class UserAction {
    /**
     * 手动实例化的弊端
     *  1.如果依赖的接口实现需要大批量改动及迭代时,维护的成本极高
     *  2.当接口的实现类不统一,维护成本更高
     */
    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 update(){
         userService.update();
         return "list";
     }
}

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.ctb.ioc.web.UserAction" id="userAction">
            <property name="userService" ref="userService"></property>
            <constructor-arg name="uname" value="奥特曼" ></constructor-arg>
            <constructor-arg name="age" value="66" ></constructor-arg>
            <constructor-arg name="hobby"  >
                <list>
                    <value>打飞机</value>
                    <value>打篮球</value>
                </list>
            </constructor-arg>
        </bean>
          <bean class="com.ctb.ioc.web.GoodsAction" id="goodsAction">
            <property name="userService" ref="userServiceImpl2"></property>
            <property name="gname" value="赵六"></property>
            <property name="age" value="18"></property>
            <property name="peoples">
                <list>
                    <value>张三</value>
                    <value>李四</value>
                    <value>王五</value>
                </list>
            </property>
        </bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl" id="userService" ></bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl2" id="userServiceImpl2"></bean>
</beans>

2.Setter方法注入

  • Setter方法注入是通过调用对象的Setter方法来设置依赖项的值。
  • 在使用Setter方法注入时,需要在类中定义相应的Setter方法,用于接收依赖项的值。
  • Spring容器会根据配置文件或注解中的定义,自动调用Setter方法,并将依赖项的值传递给对应的Setter方法。
  • Setter方法注入可以在对象创建后动态地设置依赖项的值,使得对象的依赖关系更加灵活和可变。
package com.ctb.ioc.web;
import com.ctb.ioc.service.UserService;
import java.util.List;
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"
       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">
        <bean class="com.ctb.ioc.web.UserAction" id="userAction">
         <property name="userService" ref="userServiceImpl"></property>
        </bean>
        <bean class="com.ctb.ioc.web.GoodsAction" id="goodsAction">
            <property name="userService" ref="userServiceImpl2"></property>
            <property name="gname" value="赵六"></property>
            <property name="age" value="18"></property>
            <property name="peoples">
                <list>
                    <value>张三</value>
                    <value>李四</value>
                    <value>王五</value>
                </list>
            </property>
        </bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl" id="userService" ></bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl2" id="userServiceImpl2"></bean>
</beans>

3.自动装配

  1. 根据类型(byType)自动装配:
  • 在目标对象的构造函数、Setter方法或字段上使用@Autowired注解。
  • Spring容器会根据依赖项的类型,在容器中查找匹配的对象,并自动注入到目标对象中。
  • 如果存在多个匹配的对象,可以使用@Qualifier注解指定具体的对象。
  1. 根据名称(byName)自动装配:
  • 在目标对象的构造函数、Setter方法或字段上使用@Autowired注解,并结合@Qualifier注解。
  • @Qualifier注解中指定要注入的对象的名称。
  • Spring容器会根据依赖项的名称,在容器中查找匹配的对象,并自动注入到目标对象中。
  1. 自动装配的其他选项:
  • @Autowired注解还可以与@Primary注解一起使用,指定首选的自动装配对象。
  • 如果依赖项无法找到匹配的对象,可以使用@Autowired(required = false)注解,允许依赖项为null。

byName

<?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.ctb.ioc.web.UserAction" id="userAction">
            <property name="userService" ref="userService"></property>
            <constructor-arg name="uname" value="奥特曼" ></constructor-arg>
            <constructor-arg name="age" value="66" ></constructor-arg>
            <constructor-arg name="hobby"  >
                <list>
                    <value>打飞机</value>
                    <value>打篮球</value>
                </list>
            </constructor-arg>
        </bean>
          <bean class="com.ctb.ioc.web.GoodsAction" id="goodsAction">
            <property name="userService" ref="userServiceImpl2"></property>
            <property name="gname" value="赵六"></property>
            <property name="age" value="18"></property>
            <property name="peoples">
                <list>
                    <value>张三</value>
                    <value>李四</value>
                    <value>王五</value>
                </list>
            </property>
        </bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl" id="userService" ></bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl2" id="userServiceImpl2"></bean>
</beans>

byType

<?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.ctb.ioc.web.UserAction" id="userAction">
            <property name="userService" ref="userService"></property>
            <constructor-arg name="uname" value="奥特曼" ></constructor-arg>
            <constructor-arg name="age" value="66" ></constructor-arg>
            <constructor-arg name="hobby"  >
                <list>
                    <value>打飞机</value>
                    <value>打篮球</value>
                </list>
            </constructor-arg>
        </bean>
          <bean class="com.ctb.ioc.web.GoodsAction" id="goodsAction">
            <property name="userService" ref="userServiceImpl2"></property>
            <property name="gname" value="赵六"></property>
            <property name="age" value="18"></property>
            <property name="peoples">
                <list>
                    <value>张三</value>
                    <value>李四</value>
                    <value>王五</value>
                </list>
            </property>
        </bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl" id="userService" ></bean>
        <bean class="com.ctb.ioc.service.impl.UserServiceImpl2" id="userServiceImpl2"></bean>
</beans>

五、简单属性配置与复杂属性配置

  1. 简单属性配置:
  • 简单属性配置是指设置对象的基本数据类型或字符串类型的属性值。
  • 在XML配置文件中,可以使用<property>元素来配置简单属性。
  • 例如,假设有一个名为person的JavaBean,有一个名为name的属性,可以使用以下方式进行简单属性配置:
    <bean id="person" class="com.example.Person">
    <property name="name" value="John Doe" />
</bean>
  • 在注解配置中,可以使用@Value注解来配置简单属性。
  • 例如,使用注解配置上述的person对象的name属性:
 @Value("John Doe")
private String name;
  @Value("John Doe")
private String name;
  1. 复杂属性配置:
  • 复杂属性配置是指设置对象的引用类型或集合类型的属性值。
  • 在XML配置文件中,可以使用<property>元素的ref属性来配置引用类型的属性。
  • 例如,假设有一个名为person的JavaBean,有一个名为address的属性,可以使用以下方式进行复杂属性配置:
  <bean id="person" class="com.example.Person">
    <property name="address" ref="addressBean" />
</bean>
<bean id="addressBean" class="com.example.Address">
    <!-- 设置addressBean的其他属性 -->
</bean>
  • 在注解配置中,可以使用@Autowired@Resource注解来配置引用类型的属性。
  • 例如,使用注解配置上述的person对象的address属性:
 @Autowired
private Address address;
  @Autowired
private Address address;
  • 对于集合类型的属性,可以使用<array>、<list><map><set>等元素进行配置,或者使用@Value注解配合#{}表达式进行配置。

数组(array)注入

<property name="books" >
            <array>
                <value>1</value>
                <value>12</value>
                <value>123</value>
                <value>122234</value>
            </array>
</property>

List注入

 <property name="hobbys">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
 </property>

Map注入

 <property name="card">
            <map>
                <entry key="JAVA" value="100"></entry>
                <entry key="Python" value="100"></entry>
            </map>
 </property>

Set注入

 <property name="games">
            <set>
                <value>1</value>
                <value>2</value>
            </set>
 </property>

六、spring上下文与tomcat整合

  • Spring上下文是Spring框架的核心部分,它负责管理和提供应用程序中的对象和依赖关系。
  • 在将Spring与Tomcat整合时,可以使用Spring的ContextLoaderListener来加载Spring上下文。
  • 需要在web.xml文件中配置ContextLoaderListener,并指定Spring配置文件的位置。
  • 这样,Tomcat启动时会加载Spring上下文,并将其与Web应用程序进行整合。

SpringLoadlistener.java

@WebListener
public class SpringLoadlistener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("初始化将Spring的上下文放入tomcat");
        //将Spring的上下文放入tomcat
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/Spring-Context.xml");
        //获取tomcat上下文
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("springcontext",context);
    }
}

UserServlet.java

@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 {
       //处理请求的时候获取spring上下文
        ClassPathXmlApplicationContext springcontext = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springcontext");
        UserAction useraction = (UserAction) springcontext.getBean("userAction");
        System.out.println(useraction);
        useraction.Update();
    }
}

spring ioc的讲解到这就结束啦 !!关注博主不迷路😁😁


相关文章
|
19天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
16天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
34 2
|
15天前
|
消息中间件 NoSQL Java
springboot整合常用中间件框架案例
该项目是Spring Boot集成整合案例,涵盖多种中间件的使用示例,每个案例项目使用最小依赖,便于直接应用到自己的项目中。包括MyBatis、Redis、MongoDB、MQ、ES等的整合示例。
65 1
|
18天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
10天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
22 0
|
XML Java 数据格式
Spring【依赖注入】就是这么简单(二)
在Spring的第二篇中主要讲解了Spring Core模块的使用IOC容器创建对象的问题,Spring Core模块主要是解决对象的创建和对象之间的依赖关系,因此本博文主要讲解如何使用IOC容器来解决对象之间的依赖关系!
135 0
Spring【依赖注入】就是这么简单(二)
|
Java 测试技术 容器
Spring【依赖注入】就是这么简单
前言 在Spring的第二篇中主要讲解了Spring Core模块的使用IOC容器创建对象的问题,Spring Core模块主要是解决对象的创建和对象之间的依赖关系,因此本博文主要讲解如何使用IOC容器来解决对象之间的依赖关系! 回顾以前对象依赖 我们来看一下我们以前关于对象依赖,是怎么的历程 直接new对象 在最开始,我们是直接new对象给serice的userDao属性赋值.
1189 0
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
162 2
|
8天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
20 2
 SpringBoot入门(7)- 配置热部署devtools工具