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

2024-06-21 08:52

本文主要是介绍Spring+SpringMVC介绍+bean实例化+依赖注入实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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 {@Overridepublic 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/beanshttp://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/beanshttp://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/beanshttp://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/beanshttp://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 {@Testpublic 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!");}@Testpublic 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;@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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>

这些其实都是固定写法

测试

@Testpublic 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 {}
    @Testpublic 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文件

这篇关于Spring+SpringMVC介绍+bean实例化+依赖注入实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080764

相关文章

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。