Spring+SpringMVC介绍+bean实例化+依赖注入实战

news2024/11/25 20:51:28

Spring介绍

Spring是一个轻量级的Java 开发框架,核心是IOC(控制反转)和AOP(面向切面编程)

Spring解决了业务层(Service包)与其他各层(表现层,包括Model,View,Controller三部分;持久层,jdbc和mybatis……)之间耦合度高的问题

耦合是什么?Spring如何解决高耦合的?

耦合是什么?

耦合是衡量程序模块之间互相依赖程度的指标

耦合也可以用来衡量程序拓展性和维护性

这里的依赖,不是继承关系的那种依赖

本质上指的是模块之间关联关系强弱(属性直接获取修改;直接调用方法;通过方法参数调用;使用同一全局变量;使用同一其他模块;参数为一部分成员变量……)

松耦合代表业务层和其他层之间的耦合度较低,互相依赖的程度较低,彼此之间影响小;
松耦合代表业务层和其他层之间的耦合度较高,互相依赖的程度较高,修改A的代码,B也要修改;

我们开发程序,一般都是以“高内聚,低耦合”为目标的

Spring如何解决高耦合

没有Spring之前,我们使用Servlet,JSP和JDBC作为Java开发框架,开发JavaWeb程序

JSP将业务层和视图层耦合在了一起,JDBC又将业务层和持久层耦合在了一起

Spring解决了这个问题,其中的关键在于IOC,将创建对象,使用对象,销毁对象的权力交给SpringBean容器而不是代码

IOC的关键在于DI(依赖注入)

SpringMVC简介

Model(entity包)-View(thymeleaf等视图引擎)-Controller(Controller包)

Model(模型):用来处理程序中数据逻辑的部分

View(视图):在应用程序中,专门和浏览器进行交互,展示数据的资源

Contreller(控制器):可以理解成是一个分发器,来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图,也就是用来连接视图和模型的

Spring框架的特点

  1. 方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理。IOC的作用。
  2. AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。(可扩展性)
  3. 声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。
  4. 方便程序的测试,Spring对Junit4支持,可以通过注解方便的测试Spring程序。
  5. 方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。
  6. 降低JavaEE API的使用难度,Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。

IOC简介

IOC – Inverse of Control,控制反转,将对象的创建权力反转给Spring框架!!
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。
解决问题:使用IOC可以解决的程序耦合性高的问题。Spring的工厂读取配置文件。

IOC创建的bean,默认情况下整个内存只有一份,也就是单例模式,后续的测试中可以看到这一点

IOC是思想,DI是IOC的实现方法,两者绑定

bean的实例化

准备工作

maven依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

service接口

public interface UserService {

    public void hello();

}

service接口实现类

public class UserServiceImpl implements UserService {
    @Override
    public void hello() {
        System.out.println("Hello IOC!!");
    }
}

resources下创建applicationContext.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">
   
</beans>

通过applicationContext.xml的方式实例化

1. 直接实例化

?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">
   <!--IOC管理bean-->
   <!--1. 直接实例化-->
    <bean id="userService" class="cn.tx.service.UserServiceImpl" />

</beans>

缺点:当需要加载到bean容器中的bean数量太多的时候,这样一个一个导入非常繁琐

2. 静态bean工程实例化

需要一个静态工厂类

public class StaticBeanFactory {

    // 静态工厂方式
    public static UserService staticBeanCreate() {
        System.out.println("通过静态工厂的方式创建UserServiceImpl对象...");
        return new UserServiceImpl();
    }

}

随后在xml文件中导入静态工厂bean对象即可

?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="staticUs" class="com.qcby.mySpring01.beanFactory.StaticBeanFactory" factory-method="staticBeanCreate"/>
</beans>

3. 动态工厂实例化

public class DynamicBeanFactory {
    //对象方法
    public UserService dynamicBeanCreate(){
        System.out.println("动态工厂的方式创建bean对象。。。");
        return new UserServiceImpl();
    }
}
?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="dynamicFactoryBean" class="com.qcby.mySpring01.beanFactory.DynamicBeanFactory"/>
    <bean id="dynamicUs" factory-bean="dynamicFactoryBean" factory-method="dynamicBeanCreate"/>
</beans>

通过注解实例化

@Component
@Service
@Repository
@Controller
@Mapper

bean实例化测试

public class IOCTest {

    @Test
    public void run() {

        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
/*        ApplicationContext applicationContext =
 new FileSystemXmlApplicationContext("D:\\6_WorkSpace\\shiXun\\spring01\\src\\main\\resources\\applicationContext.xml");*/
        UserService userService = (UserService) applicationContext.getBean("userService");
        UserService userService1 = (UserService) applicationContext.getBean("userService");
        System.out.println(userService);
        System.out.println(userService1);
        userService.hello("IOC!");
    }


    @Test
    public void factoryBeanTest() {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService staticBean = (UserService) applicationContext.getBean("staticUs");
        UserService dynamicBean = (UserService) applicationContext.getBean("dynamicUs");

        staticBean.hello("staticFactory");
        dynamicBean.hello("dynamicFactory");
    }
}

在这里插入图片描述
在这里插入图片描述

依赖注入

DI:Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时(bean实例化),
动态的将依赖对象(对象的属性)注入到Bean组件中

通过applicationContext.xml的方式注入

set方法注入

必须保证setter方法存在,否则会报错

public class CarServiceImpl implements CarService {

    private CarDao carDao;

    @Override
    public String toString() {
        return "CarServiceImpl{" +
                "msg='" + msg + '\'' +
                ", id=" + id +
                '}';
    }

    private String msg;
    private Integer id;

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setCarDao(CarDao carDao) {
        this.carDao = carDao;
    }

    public List<Car> findAll() {
        List<Car> carList = carDao.findAll();
        return carList;
    }
}

<!--set方法DI注入-->
    <bean id="carDao" class="com.qcby.mySpring01.mapper.impl.CarDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="carService" class="com.qcby.mySpring01.service.impl.CarServiceImpl">
        <property name="carDao" ref="carDao"/>
        <property name="msg" value="你好"/>
        <property name="id" value="100"/>
    </bean>

构造方法注入

public class Car {
    private int id;

    private String carName;

    private int size;

    private String color;

    public Car() {
    }

    public Car(String carName, int size, String color) {
        this.carName = carName;
        this.size = size;
        this.color = color;
    }

    @Override
    public String toString() {
        return "Car{" +
            "id=" + id +
            ", carName='" + carName + '\'' +
            ", size=" + size +
            ", color='" + color + '\'' +
            '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCarName() {
        return carName;
    }

    public void setCarName(String carName) {
        this.carName = carName;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

<!--构造器DI注入-->
    <bean id="car1" class="com.qcby.mySpring01.pojo.Car">
        <!--        <constructor-arg index="0" value="小米Su7 Pro Max"/>
                <constructor-arg index="1" value="10"/>
                <constructor-arg index="2" value="blue"/>-->
        <constructor-arg name="carName" value="小米Su7 Pro Max"/>
        <constructor-arg name="size" value="10"/>
        <constructor-arg name="color" value="blue"/>
    </bean>
    <bean id="car2" class="com.qcby.mySpring01.pojo.Car">
        <!--        <constructor-arg index="0" value="小米Su7 Pro Max"/>
                <constructor-arg index="1" value="10"/>
                <constructor-arg index="2" value="blue"/>-->
        <constructor-arg name="carName" value="BYD秦PLUS DMI"/>
        <constructor-arg name="size" value="198"/>
        <constructor-arg name="color" value="black"/>
    </bean>

通过接口注入

(暂时略,后续补充)

数组,集合(List,Set,Map),Properties等的注入

public class CollectionBean {

    // 数组
    private Student[] studentArr;

    public void setStudentArr(Student[] studentArr) {
        this.studentArr = studentArr;
    }

    private List<String> list;

    public void setList(List<String> list) {
        this.list = list;
    }

    private Map<String, String> map;

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    private Map<Student, Car> studentCarMap;
    public void setStudentCarMap(Map<Student, Car> studentCarMap) {
        this.studentCarMap = studentCarMap;
    }

    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "studentArr=" + Arrays.toString(studentArr) +
                ", list=" + list +
                ", map=" + map +
                ", studentCarMap=" + studentCarMap +
                ", properties=" + properties +
                '}';
    }
}
<!--引用类型/集合注入-->
    <bean id="student1" class="com.qcby.mySpring01.pojo.Student">
        <property name="name" value="张三"/>
        <property name="age" value="15"/>
        <property name="grade" value="7"/>
    </bean>
    <bean id="student2" class="com.qcby.mySpring01.pojo.Student">
        <property name="name" value="李四"/>
        <property name="age" value="14"/>
        <property name="grade" value="6"/>
    </bean>
    <bean id="student3" class="com.qcby.mySpring01.pojo.Student">
        <property name="name" value="王五"/>
        <property name="age" value="18"/>
        <property name="grade" value="13"/>
    </bean>
    <bean id="collectionBean" class="com.qcby.mySpring01.pojo.CollectionBean">
        <property name="studentArr">
            <array>
                <ref bean="student1"/>
                <ref bean="student2"/>
                <ref bean="student3"/>
            </array>
        </property>
        <property name="list">
            <list>
                <value>熊大</value>
                <value>熊二</value>
                <value>吉吉国王</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="111" value="aaa"/>
                <entry key="222" value="bbb"/>
            </map>
        </property>
        <property name="studentCarMap">
            <map>
                <entry key-ref="student1" value-ref="car1"/>
                <entry key-ref="student2" value-ref="car2"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>

    </bean>

这些其实都是固定写法

测试

@Test
    public void DITest() {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        CarService carService = (CarService) applicationContext.getBean("carService");
        // set方法注入
        System.out.println(carService);
        List<Car> carList = carService.findAll();
        for (Car car : carList) {
            System.out.print(car.getCarName() + "\t");
        }
        System.out.println();
        // 构造方法注入
        Car car1 = (Car) applicationContext.getBean("car1");
        System.out.println(car1);

        // 数组,集合(List,Set,Map),Properties注入
        CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("collectionBean");
        System.out.println(collectionBean);

    }

在这里插入图片描述

通过注解注入

依赖注入常用的注解
@Value 用于注入普通类型(String,int,double等类型)
@Autowired 默认按类型进行自动装配(引用类型)
@Qualifier 和@Autowired一起使用,强制使用名称注入
@Resource Java提供的注解,也被支持。使用name属性,按名称注入
对象生命周期(作用范围)注解
@Scope 生命周期注解,取值singleton(默认值,单实例)和prototype(多例)
初始化方法和销毁方法注解(了解)
@PostConstruct 相当于init-method
@PreDestroy 相当于destroy-method

@Service
@Qualifier("studentServiceImpl")
public class StudentServiceImpl implements StudentService {
    public void listAll() {
        System.out.println("studentService2");
    }
}

@Service
@Qualifier("studentServiceImpl2")
public class StudentServiceImpl2 implements StudentService {
    public void listAll() {
        System.out.println("studentService2");
    }
}

@Configuration
@ComponentScan("com.qcby")
@Import({SpringConfig2.class})// 多配置文件
public class SpringConfig {


}
    @Test
    public void qualifierTest() {
        ApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(SpringConfig.class);
//        ApplicationContext applicationContext =
//                new ClassPathXmlApplicationContext("applicationContext_anno.xml");
/*        ApplicationContext applicationContext =
 new FileSystemXmlApplicationContext("D:\\6_WorkSpace\\shiXun\\spring01\\src\\main\\resources\\applicationContext_anno.xml");*/
        StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");
        StudentService studentService2 = (StudentService) applicationContext.getBean("studentServiceImpl2");
        System.out.println(studentService);
        System.out.println(studentService2);
        studentService.listAll();
        studentService2.listAll();
    }

在这里插入图片描述

纯注解不需要写applicationContext.xml文件

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

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

相关文章

无版权图片素材搜索网站,解决无版权图片查找问题

在数字内容创作领域&#xff0c;图片素材的选择至关重要。一张高质量、合适的图片不仅能够吸引读者的眼球&#xff0c;还能有效传达信息。然而&#xff0c;找到既免费又无版权限制的图片素材并非易事。小编将为大家介绍几个解决这一问题的无版权图片素材搜索网站&#xff0c;这…

程序猿大战Python——面向对象——对象属性

什么是属性 目标&#xff1a;了解什么是属性&#xff1f; 在现实生活中&#xff0c;属性就表示固有特征&#xff0c;比如&#xff1a;一辆小轿车的属性有轮胎数、颜色、品牌等。 仔细观察后会发现&#xff0c;属性可以简单理解为与生俱来的特征&#xff0c;比如一个人的姓名、年…

Lazada API接口——一键获取商品买家评论数据信息

一、引言 在电商领域&#xff0c;买家评论是商品销售中不可忽视的重要因素。它们不仅影响着潜在消费者的购买决策&#xff0c;还为商家提供了宝贵的客户反馈。为了满足商家和数据分析师对买家评论数据的需求&#xff0c;我们特别开发了一款针对Lazada平台的接口&#xff0c;其…

30分钟完成一个AI视频,跑通0到1的过程,包含文生图,图生视频的制作

关注公众号&#xff0c;赠送AI/Python/Linux资料 步骤一&#xff1a;写故事 需要给出故事情节&#xff0c;让kimi首先提供一个提示词模版 提示词输入后&#xff0c;就让kimi开始写故事了 一个完整的故事就出来了 非常好&#xff0c;描述一个IT人的一生是一个宏大的主题&#…

后台管理台字典localStorage缓存删除

localStorage里存放了如以下dictItems_开头的字典数据&#xff0c;localStorage缓存是没有过期时间的&#xff0c;需要手动删除。同时localStorage里还存有其他不需要删除的数据。 这里的方案是遍历localStorage&#xff0c;利用正则和所有key进行匹配&#xff0c;匹配到dict…

【有手就会】图数据库Demo教程,实现《诡秘之主》中的人物关系探索

前言 星环社区版家族于近期发布了单机、30s一键启动的StellarDB图数据库&#xff0c;本篇文章将为用户介绍如何使用开发版StellarDB实现人物关系探索。 友情链接&#xff1a;白话大数据 | 关于图数据库&#xff0c;没有比这篇更通俗易懂的啦 TDH社区版本次发布StellarDB社区…

如何选择合适的半桥栅极驱动芯片?KP8530X,KP85402,KP85211A满足你对半桥栅极驱动一切需求

半桥栅极驱动系列KP8530X&#xff0c;KP85402&#xff0c;KP85211A在功率电子领域展现出卓越的性能和可靠的品质。具备诸多显著优势。首先&#xff0c;半桥栅极驱动系列KP8530X&#xff0c;KP85402&#xff0c;KP85211A拥有出色的耐压性能&#xff0c;可承受高达数百伏的电压&a…

ArcGIS制作规划图卫星影像地图虚化效果

文章目录 一、效果展示二、加载数据三、效果制作四、注意事项一、效果展示 二、加载数据 订阅专栏后,从csdn私信查收实验数据资料,加载ArcGIS制作规划图卫星影像地图虚化效果.rar中的数据,如下所示: 三、效果制作 1. 创建掩膜图层 新建一个矢量图层,因为主要是作图需要…

GNSS边坡监测站

TH-WY1随着科技的飞速发展&#xff0c;各种先进的监测技术不断涌现&#xff0c;为边坡安全监测提供了有力保障。其中&#xff0c;GNSS边坡监测站以其高精度、实时性强的特点&#xff0c;受到了广泛关注。 GNSS边坡监测站&#xff0c;全称为全球导航卫星系统边坡监测站&#xf…

1.接口测试-postman学习

目录 1.接口相关概念2.接口测试流程3.postman基本使用-创建请求&#xff08;1&#xff09;环境&#xff08;2&#xff09;新建项目集合Collections&#xff08;3&#xff09;新建collection&#xff08;4&#xff09;新建模块&#xff08;5&#xff09;构建请求请求URLheader设…

湖南省物联网挑战赛教学平台使用说明文档

1物联网教学平台硬件连接 1.1硬件介绍 1&#xff09;物联网教学平台实验箱 2&#xff09;物联网硬件平台 3&#xff09;无线传感器节点 4&#xff09;智能烧录平台 1.2连线 注&#xff1a;智能烧录平台上的USB接口必须与物联网硬件平台“开关”那一面最右侧USB接口连接 1.3修…

小红书xs-xt解密

在进行小红书爬虫的时候,有一个关键就是解决动态密文的由来 这边用atob对X-S密文进行解密 可以看到他是一个字符串 可以发现他本来是一个json对象,因为加密需要字符串,所以将json对象转化 为了字符串 而在js中,常用JSON.stringify进行json对象到字符串的转化。 这边将JS…

java中atomic(原子包)常用类详解

目录 一、简介 二、分类 2.1 基本类型原子类 2.1.1 AtomicInteger和AtomicLong介绍 2.1.1.1 AtomicInteger常用的API源码和注释 2.1.1.2 AtomicInteger常用API使用案例 2.1.2 AtomicBoolean介绍 2.1.2.1 AtomicBoolean常用API源码和注释 2.1.2.2 AtomicBoolean常用API…

MVC模式中控制器、视图和模型之间的关系如何?

mvc模式将应用程序逻辑与表示层分离&#xff0c;包括控制器、视图和模型三个组件&#xff1a;控制器&#xff1a;协调用户输入&#xff0c;获取模型数据&#xff0c;验证输入&#xff0c;执行业务规则。视图&#xff1a;显示模型数据&#xff0c;不包含业务逻辑。模型&#xff…

大厂薪资福利篇第三弹:阿里巴巴

为什么计算机学子对大厂趋之若鹜呢&#xff1f;最直接的原因就是高薪资的吸引力。 • 但是薪资可不是简单的数字哦&#xff0c;里面还是有很多“学问”的。 • 很多同学对大厂薪资只有一个模糊的了解&#xff0c;知道大厂的年薪高达三十四十万甚至五十万&#xff0c;但是对具体…

【鸿蒙】HUAWEI DevEco Studio安装

HUAWEI DevEco Studio介绍 面向HarmonyOS应用及元服务开发者提供的集成开发环境(IDE)&#xff0c; 助力高效开发。 DevEco Studio当前最新版本是&#xff1a; 3.1。 DevEco Studio计划里程碑 版本类型说明 下载 下载网址&#xff1a;DevEco Studio安装包官⽅下载 双击运行…

Linux_理解进程地址空间和页表

目录 1、进程地址空间示意图 2、验证进程地址空间的结构 3、验证进程地址空间是虚拟地址 4、页表-虚拟地址与物理地址 5、什么是进程地址空间 6、进程地址空间和页表的存在意义 6.1 原因一&#xff08;效率性&#xff09; 6.2 原因二&#xff08;安全性&#xff09; …

【CT】LeetCode手撕—236. 二叉树的最近公共祖先

目录 题目1- 思路2- 实现⭐236. 二叉树的最近公共祖先——题解思路 3- ACM实现 题目 原题连接&#xff1a;236. 二叉树的最近公共祖先 1- 思路 模式识别 模式1&#xff1a;二叉树最近公共祖先 ——> 递归 判断 递归思路&#xff0c;分情况判断&#xff1a; 1.参数及返…

【IEEE独立出版、有确定的ISBN号】第三届能源与电力系统国际学术会议 (ICEEPS 2024)

第三届能源与电力系统国际学术会议 (ICEEPS 2024) 2024 3rd International Conference on Energy and Electrical Power Systems 连续2届会后4-5个月EI检索&#xff0c;检索稳定&#xff01; 成功申请IEEE出版&#xff01; 特邀院士、Fellow 报告&#xff01; 一、大会信息 …

nexus配置问题

错误信息&#xff1a; npm ERR! code E401 npm ERR! Unable to authenticate, need: BASIC realm"Sonatype Nexus Repository Manager"解决办法一&#xff1a; npm login --registryhttp://192.168.52.128:8081/repository/npm-repo 输入 用户名 密码 邮箱完成后会…