-
M —— modal 模型层(实体类)
-
V —— views 视图层 (界面)
-
C —— controller 控制层 (用来完执行一些操作)
这三层架构各自分工,独自完成相对应的功能,但是这样的程序写出来会导致程序之间耦合性过高
1.2 程序耦合性过高?
耦合性过高实际上说的是程序之间的依赖性过高,解耦说的就是降低程序之间的依赖关系
我们使用 Java 通常都是写好一个类,构造方法,setter 和 getter 等等,我们在其他的类中使用该类就得 创建一个 该类的对象,然后通过对象调用该类的各种方法。这样整个程序之间就会产生多个类,对应的也会产生多个对象互相进行调用,因此我们整体的程序就会体现出耦合性过高的特点。
1.3 如何解耦?
-
我们在 Java SE 中学习过 JDBC,也学习过 properties 对象, 我们可以把 jdbc 的一些配置写进文件中。
-
我们传统一般都是创建对象,我们可以换一种方式,通过 Java 的反射机制获取类的信息,并且创建对象
-
读取 xml 文件
1.4 Spring IOC 的依赖注入
Spring 框架正式为了解决这样的情况出现了,它提供了 读取 xml配置,以及注解 两种方式实现 bean 的自动注入,而被注入的容器叫做 IOC 容器
依赖注入:
Dependency Injection
IOC 的作用:
降低程序键的耦合(依赖关系)
依赖关系的管理:
以后都交给 spring 来维护
在当前类需要用到其他类的对象,由Spring来为我们提供,我们只需要在配置文件中说明
依赖关系的维护:
就称为依赖注入
依赖注入:
能注入的数据,有三类
基本类型和 string
其他 bean 类型(在配置文件中或者注解配置过的 bean—)
复杂类型、集合类型
注入的方式:有三种
第一种:使用构造函数提供
第二种:使用 set方法提供
第三种:使用注解提供
二、Spring IOC 的依赖注入(使用 xml 完成注入)
==============================================================================================
2.1 使用构造函数完成依赖注入
2.1.1 标签的使用讲解
-
使用的标签:constructor-arg
-
标签出现的位置:bean标签的内部
-
标签中的属性
1. type:用于指定要注入的数据的数据类型,该数据类型可以是构造函数中某个或某些参数的类型
2. index: 用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引的位置也是从 0 开始
3. name:用于指定构造函数中指定名称的参数赋值
以上三个标签用于指定给构造函数中哪个参数赋值
5. value: 用于给基本类型和 String类型的数据
6. ref:用于指定其它的 bean 类型数据,它指的就是 spring IOC 核心容器中出现过的 bean 对象
2.1.2 构造函数依赖注入的优缺点
- 优势:
在获取 bean 对象时,注入数据是必须的操作,否则对象无法创建成功
- 弊端:
改变了bean 对象的实例化方式,使我们在创建对象时,如果用不到,也必须创建
2.1.3 使用构造函数完成依赖注入的实例
注意:后面的修改全部都是基于此类的修改在这里插入代码片
-
编写 bean.xml 配置文件
-
编写一个 AccountService 接口,后面的三种方法都要实现该接口
-
编写 AccountServiceImpl 实现该接口,并且记住该类的名称和位置
-
编写一个 Client 类,用来测试该接口中的方法
bean.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”
xmlns:context=“http://www.springframework.org/schema/context”
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
IAccountService 接口编写
package com.itheima.service;
public interface IAccountService {
void saveAccount();
}
IAccountServceImpl 接口实现类的编写
package com.itheima.service.impl;
import com.itheima.service.IAccountService;
import java.util.Date;
/**
-
账户业务层的实现类
-
构造函数的注入
-
*/
public class IAccountServceImpl implements IAccountService {
// 经常变化的数据,并不适用于注入的方式
private String name;
private Integer age;
private Date birthday;
// 创建有参的构造方法,这个方法必须存在, 在xml中,数据就是通过有参的构造方法擦混入的
public IAccountServceImpl(String name, Integer age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public IAccountServceImpl() {
System.out.println(“对象创建了”);
}
public void saveAccount() {
System.out.println(“service 中的 saveAccount 方法执行了”+this.name + " "+ this.age + " " + this.birthday);
}
@Override
public String toString() {
return “IAccountServceImpl{” +
“name='” + name + ‘’’ +
“, age=” + age +
“, birthday=” + birthday +
‘}’;
}
}
Client 类的编写
package com.itheima.client;
import com.itheima.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
-
模拟一个表现层,用于调用业务层
-
*/
public class Client {
public static void main(String[] args) {
// 使用 mvc 三层架构,编写 (耦合性过高)
// IAccountService as = new IAccountServceImpl();
// =============== 划重点 ===============
// 1. 获取核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext(“bean.xml”);
// ApplicationContext ac = new FileSystemXmlApplicationContext(“xxx”); // 这里填写配置文件,在你本机上的物理地址,很少用户
// 2. 根据 id 获取 Bean 对象 (方式一)
IAccountService as = (IAccountService) ac.getBean(“accountService”);
System.out.println(as);
as.saveAccount();
//2. 根据 id 获取 Bean 对象 (方式二)
// IAccountDao adao = ac.getBean(“accountDao”, IAccountDao.class);
// as.saveAccount();
// System.out.println(adao);
}
}
运行结果:
我们没有使用 传统的方式,接用 Spring 框架完成了 bean 的实例化
2.2 使用 setter 完成注入
2.2.1 使用 setter 完成依赖注入的功能
涉及的标签:property
出现的位置:bean 标签的内部
标签的属性:
name:用于指定注入时所用的 set 方法名称
== 以上三个用于指定给构造函数中哪个参数赋值 ==
value: 用于给基本类型和 String类型的数据
ref:用于指定其它的 bean 类型数据,它指的就是 spring IOC 核心容器中出现过的 bean 对象
2.2.2 基于 setter 完成依赖注入的分析
- 优势:
创建对象时没有明确的限制,可以直接使用默认构造函数
- 弊端:
如果某个成员必须有值,则获取对象可能 set 方法没有执行
有了前面的内容做铺垫,接下来做 setter 注入就会轻松很多,我们需要做如下步骤
- 在 bean.xml 添加依赖
- 编写 IAccountServiceImpl2
package com.itheima.service.impl;
import com.itheima.service.IAccountService;
import java.util.Date;
/**
-
setter 注入
-
*/
public class IAccountServiceImpl2 implements IAccountService {
private String name;
private Integer age;
private Date birthday;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return “IAccountServiceImpl2{” +
“name='” + name + ‘’’ +
“, age=” + age +
“, birthday=” + birthday +
‘}’;
}
public void saveAccount() {
System.out.println(“service 中的 saveAccount 方法执行了”);
}
}
- Client 内容修改
package com.itheima.client;
import com.itheima.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
-
模拟一个表现层,用于调用业务层
-
*/
public class Client {
public static void main(String[] args) {
// 1. 获取核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext(“bean.xml”);
// 2. 根据 id 获取 Bean 对象 (两种方式)
IAccountService as = (IAccountService) ac.getBean(“accountService2”);
System.out.println(as);
as.saveAccount();
}
}
- 效果图(数据成功通过 setter 注入)
2.2.3 基于 setter 注入的简化操作
约束新增 p 标签
<?xml version="1.0" encoding="UTF-8"?><beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:p=“http://www.springframework.org/schema/p”
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
2.3 复杂数据类型注入
2.3.1 集合数据类型注入使用场景
复杂类型的注入,集合类型的注入
常用 list 和 map
用于给 List 结构集合注入的标签
list array set
用于给 Map 结构集合注入的标签
map props
结构相同,标签可以互换
2.3.2 集合类型的数据注入
- bean.xml 的配置
AAA
BBB
CCC
AAA
BBB
CCC
AAA
BBB
CCC
BBB
CCC
DDD
- IAccountServiceImpl3 编写
package com.itheima.service.impl;
import com.itheima.service.IAccountService;
import java.util.*;
public class IAccountServiceImpl3 implements IAccountService {
private String[] myStrs;
private List myList;
private Set mySet;
private Map<String,String> myMap;
private Properties myPros;
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public void setMyList(List myList) {
this.myList = myList;
}
public void setMySet(Set mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMyPros(Properties myPros) {
this.myPros = myPros;
}
public void saveAccount() {
System.out.println(Arrays.toString(myStrs));
System.out.println(myList);
System.out.println(mySet);
System.out.println(myMap);
System.out.println(myPros);
}
@Override
public String toString() {
return “IAccountServiceImpl3{” +
“myStrs=” + Arrays.toString(myStrs) +
“, myList=” + myList +
“, mySet=” + mySet +
“, myMap=” + myMap +
“, myPros=” + myPros +
‘}’;
}
}
- Client 编写
package com.itheima.client;
import com.itheima.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
public static void main(String[] args) {
// 1. 获取核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext(“bean.xml”);
// 2. 根据 id 获取 Bean 对象 (两种方式)
IAccountService as = (IAccountService) ac.getBean(“accountService3”);
System.out.println(as);
as.saveAccount();
}
}
- 效果图
=======================================================================================
bean.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”
xmlns:context=“http://www.springframework.org/schema/context”
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package=“com.itheima”></context:component-scan>
编写 IAccountService 接口
package com.itheima.service;
public interface IAccountService {
void saveAccount();
}
编写 IAccountDao 接口
package com.itheima.dao;
/**
-
账户持久层接口
-
*/
public interface IAccountDao {
/**
-
模拟保存账户
-
*/
void saveAccount();
}
3.1 用于创建对象的注解
我们在这里实现 IAccountService 接口 创建 IAccountServiceImpl类
3.1.1 普通方法创建对象
package com.itheima.service.impl;
/* 曾经的 xml 配置,我们要在这里协商这么一大段的 xml 才可以完成注入
-
<bean id=“accountService”
-
class="com.itheima.service.impl.IAccountServceImpl
-
<property name="" value="" | ref =""></property>
-
"/>
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/60712c8b12150536e0b99c80e6623210.jpeg)
那么如何才能正确的掌握Redis呢?
为了让大家能够在Redis上能够加深,所以这次给大家准备了一些Redis的学习资料,还有一些大厂的面试题,包括以下这些面试题
-
并发编程面试题汇总
-
JVM面试题汇总
-
Netty常被问到的那些面试题汇总
-
Tomcat面试题整理汇总
-
Mysql面试题汇总
-
Spring源码深度解析
-
Mybatis常见面试题汇总
-
Nginx那些面试题汇总
-
Zookeeper面试题汇总
-
RabbitMQ常见面试题汇总
JVM常频面试:
Mysql面试题汇总(一)
Mysql面试题汇总(二)
Redis常见面试题汇总(300+题)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
OPPO等大厂,18年进入阿里一直到现在。**
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-FjemzYHm-1713694476214)]
[外链图片转存中…(img-LZPiJLHM-1713694476214)]
[外链图片转存中…(img-Qm6LLFMq-1713694476214)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/60712c8b12150536e0b99c80e6623210.jpeg)
那么如何才能正确的掌握Redis呢?
为了让大家能够在Redis上能够加深,所以这次给大家准备了一些Redis的学习资料,还有一些大厂的面试题,包括以下这些面试题
-
并发编程面试题汇总
-
JVM面试题汇总
-
Netty常被问到的那些面试题汇总
-
Tomcat面试题整理汇总
-
Mysql面试题汇总
-
Spring源码深度解析
-
Mybatis常见面试题汇总
-
Nginx那些面试题汇总
-
Zookeeper面试题汇总
-
RabbitMQ常见面试题汇总
JVM常频面试:
[外链图片转存中…(img-WjZUHjns-1713694476215)]
Mysql面试题汇总(一)
[外链图片转存中…(img-OKUA89Ll-1713694476215)]
Mysql面试题汇总(二)
[外链图片转存中…(img-dT63SwMO-1713694476216)]
Redis常见面试题汇总(300+题)
[外链图片转存中…(img-IAcmMTLh-1713694476216)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!