Spring1
- 创建项目
- 集成maven
- 创建一个Maven项目
- 实现:
- 初识Spring
- Spring简介
- Spring的发展历史
- Spring之父
- 体系结构
- 生态系统
- 官方文档
- 解耦实现
- JDBC
- SpringBoot整合MyBatis和lombok,开启驼峰映射
- 三层思想
- SpringIOC
- 实现
- SpringDI
- set注入
- 全部代码:
- 实现:set注入基本数据类型与String
- 实现:set注入javabean对象
- 实现:set注入复杂类型
- 构造注入:
- 全部代码:
- 实现:构造注入基本类型与String类型
- 实现:构造注入javabean对象
- Spring常见面试题
- Spring 框架的基本理解
- Spring 框架由哪些模块组成?
- Spring IOC的理解
- Spring IOC容器的理解
- Spring DI的理解
创建项目
集成maven
创建一个Maven项目
实现:
在pom配置依赖:
初识Spring
Spring简介
Spring是分层的轻量级开源框架,以IoC[反转控制]和AoP[面向切面编程]为内核,提供了展现层SpringMVC和持久层SpringJDBC以及业务层的事务管理。
Spring 是分层的 Java SE/EE 应⽤ full-stack 轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切⾯编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,逐渐成为使⽤最多的 Java EE 企业应⽤开源框架。
官方网站:https://spring.io/
Spring的发展历史
企业级应用指的是 大规模、性能和安全要求高、业务复杂、灵活多变 的大型 WEB 应用程序。
- 大规模:用户量和 IP/PV访问量大、海量数据、功能模块多代码量大。
- 业务复杂:涉及金融、期货、电信等特殊领域的业务逻辑复杂,对系统架构提出新要求。
- 性能和安全要求高:响应毫秒数和安全级别均有很高的要求。
- 灵活多变:经常性的业务变更,也对开发效率以及项目部署等工作有更高的要求。
重量级技术向轻量级开发过度
为了实现企业级应用开发各类需求,涌现出以EJB为代表的一系列技术。
Spring之父
Rod Johnson,SpringFramework创始人, interface21 CEO。
• 1996 年开始关注 Java 服务器端技术
• Servlet2.4 和 JDO2.0 专家组成员
• Expert One-to-One J2EE Design and Development(2002)
• 阐述了 J2EE 使用EJB 开发设计的优点及解决方案
• Expert One-to-One J2EE Development without EJB(2004)
• 阐述了 J2EE 开发不使用 EJB的解决方式(Spring 雏形 )
• 2004年3月24日发布了Spring Framework 1.0 final
技术主张:技术应当回归实用为主,简化 Java 开发
Spring的理论基础:Spring 框架建立在本书中对于J2EE企业级应用的开发与设计的核心理念之上,追求简洁、轻量级的开发方式,让系统具备更好的健壮性和可扩展性。
体系结构
- Spring Core:Spring框架的最基础部分,提供DI(依赖注入)特性。
- Spring Context:Spring上下文,提供Bean容器的集合。
- Spring AOP:基于Spring Core的符合规范的切面编程的实现。
- Spring JDBC:提供了JDBC的抽象层,简化了JDBC编码。
- Spring ORM:对主流ORM框架(Hibernate、Toplink等)进行集成。
- Spring Web:为Spring在Web应用程序中的使用提供了支持。
生态系统
- Spring Boot:简化产品级的 Spring 应用和服务的创建,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用微服务功能。
- Spring Data:是一个数据访问及操作的工具包,封装了很多种数据及数据库的访问相关技术,包括:jdbc、Redis、MongoDB、Neo4j等。
- Spring AMQP:消息队列操作的工具包,主要是封装了RabbitMQ的操作。
- Spring Cloud:微服务工具包,用于创建基于云计算架构的原生微服务应用。
- Spring Security:是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。
- Spring Mobile:是Spring MVC的扩展,用来简化手机上的Web应用开发。
Spring【Spring FrameWork】解决的问题:
官方文档
Spring文档:https://docs.spring.io/spring-framework/docs/5.2.25.RELEASE/spring-framework-reference/core.html#spring-core
解耦实现
Spring的两大核心思想:IOC和AOP
- SpringIOC(控制反转)SpringDI(依赖注入)
- SpringAOP(面向切面思想)
SpringIOC:SpringIOC容器扮演项目的载体,IOC容器是可以使项目更符合高内聚,低耦合的思想“解耦”
耦合:类与类之间有耦合,方法与方法有耦合
解耦:
- 尽量避免new对象,通过反射实例化
- 需要创建的对象不要写死,而是把类名保存在独立的Properties文件中按需加载
JDBC
package com.stringzhua;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @Author Stringzhua
* @Date 2024/9/9 19:30
* description:
*/
class Test01 {
public static void main(String[] args) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection root = DriverManager.getConnection("jdbc:mysql://localhost:3306/lmonkeyshop?serverTimezone=GMT", "root", "12345678");
System.out.println(root);
} catch (ClassNotFoundException exception) {
exception.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
SpringBoot整合MyBatis和lombok,开启驼峰映射
=================mybaits自动驼峰映射====================
JavaBean DB
stuId stu_id
stuName stu_name
<!--自动驼峰映射-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
=================junit====================
含义:方法级别的单元测试工具
步骤:
1.坐标
2.注解
@Test=============main
@Before===========main执行之前
@After============main执行之后
=================lombok====================
步骤:
1.idea安装插件(只安装一次)
2.坐标
3.注解
项目结构如下:
Dao层:
StudentMapper.java
package com.stringzhua.dao;
import com.stringzhua.pojo.Student;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @Author Stringzhua
* @Date 2024/9/9 16:08
* description:mybatis 的 mapper
*/
public interface StudentMapper {
@Select("select * from student")
public List<Student> findAll();
@Insert("insert into student(stu_name,nick_name,stu_age) values (#{stuName},#{nickName},#{stuAge})")
public void add(Student s);
}
mybatis.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--自动驼峰映射-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--开发模式-->
<environments default="env">
<environment id="env">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mavendb?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</dataSource>
</environment>
</environments>
<!--映射器注册-->
<mappers>
<package name="com.stringzhua.dao"/>
</mappers>
</configuration>
POJO层:
Stundet.java
package com.stringzhua.pojo;
import lombok.*;
import java.io.Serializable;
/**
* @Author Stringzhua
* @Date 2024/9/9 16:03
* description:
*/
/**
* @AllArgsConstructor 满参构造
* @NoArgsConstructor 无参构造
* @ToString toString方法
* @Getter getter方法
* @Setter setter方法
* @Data 提供类的get、set、equals、hashCode、canEqual、toString方法
*
* canEqual
* 除非您的类 isfinal和 extends java.lang.Object,
* 否则 lombok 会生成一个canEqual方法,这意味着 JPA 代理
* 仍然可以等于它们的基类,但是添加新状态的子类不会破坏 equals 契约。
*/
@NoArgsConstructor
@Data
public class Student implements Serializable {
private int stuId;
private String stuName;
private String nickName;
private int stuAge;
public Student(String stuName, String nickName, int stuAge) {
this.stuName = stuName;
this.nickName = nickName;
this.stuAge = stuAge;
}
}
单元测试:
package com.stringzhua.test;
import com.stringzhua.pojo.Student;
import com.stringzhua.dao.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @Author Stringzhua
* @Date 2024/9/9 16:14
* description:
* @Before 指的是@Test注解运行之前要执行的方法
* @Test 指的是要执行测试的方法
* @After 指的是@Test注解运行之后执行的方法
*/
public class Test01 {
SqlSession sqlSession = null;
StudentMapper studentmapper = null;
@Before
public void beforeMethod() {
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(inputStream);
sqlSession = factory.openSession(true);
studentmapper = sqlSession.getMapper(StudentMapper.class);
} catch (IOException e) {
e.printStackTrace();
}
}
@After
public void afterMethod() {
sqlSession.close();
}
@Test
public void show1() throws Exception {
studentmapper.add(new Student("猫猫", "千逐", 18));
studentmapper.add(new Student("田欣怡", "晞苒", 22));
}
@Test
public void show2() throws Exception {
List<Student> all = studentmapper.findAll();
for (int i = 0; i < all.size(); i++) {
Student student = all.get(i);
System.out.println(student);
}
}
}
三层思想
项目结构如下:
首先需要在main—>resources下新建一个properties配置文件
service=com.stringzhua.service.UserServiceImpl
dao=com.stringzhua.dao.UserDaoImpl
Controller层:
IUserController.java
package com.stringzhua.controller;
public interface IUserController {
public void save();
}
UserControllerImpl.java
package com.stringzhua.controller;
import com.stringzhua.service.IUserService;
import com.stringzhua.util.BeansFactory;
public class UserControllerImpl implements IUserController {
//耦合度高
// IUserService service = new UserServiceImp();
//耦合度低,通过工厂创建service对象
IUserService service = (IUserService) BeansFactory.getBean("service");
public void save() {
System.out.println("===controller的新增===");
service.save();
}
}
Dao层:
IUserDao.java
package com.stringzhua.dao;
public interface IUserDao {
public void save();
}
UserDaoImpl.java
package com.stringzhua.dao;
public class UserDaoImpl implements IUserDao{
public void save() {
System.out.println("===dao的新增===");
}
}
Service层:
IUserService.java
package com.stringzhua.service;
public interface IUserService {
public void save();
}
UserServiceImpl.java
package com.stringzhua.service;
import com.stringzhua.dao.IUserDao;
import com.stringzhua.util.BeansFactory;
public class UserServiceImpl implements IUserService{
//耦合度高
// IUserDao dao = new UserDaoImp();
//耦合度低,通过工厂去创建dao对象
IUserDao dao = (IUserDao) BeansFactory.getBean("dao");
public void save() {
System.out.println("===serivce的新增===");
dao.save();
}
}
Utils工具类:
BeansFactory.java
package com.stringzhua.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeansFactory {
static Properties properties;
static {
try {
//1.工具类
properties = new Properties();
//2.加载文件
InputStream resourceAsStream = BeansFactory.class.getClassLoader().getResourceAsStream("beans.properties");
properties.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object getBean(String key) {
Object object = null;
try {
//1.获取key对应的value
String classPath = properties.getProperty(key);
//2.创建对象,反射,newInstance()去创建对象
object = Class.forName(classPath).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException exception) {
exception.printStackTrace();
}
return object;
}
}
测试:
package com.stringzhua.test;
import com.stringzhua.controller.IUserController;
import com.stringzhua.controller.UserControllerImpl;
public class Test01 {
public static void main(String[] args) {
IUserController controller = new UserControllerImpl();
controller.save();
}
}
SpringIOC
Spring环境搭建:
坐标---->配置文件
SpringIOC:控制反转
关键字:IOC名词解释,作用是解耦,使用IOC容器管理项目组件之间的耦合关系
IOC(Inversion Of Control 中文释义:控制反转)是Spring框架的核心思想之一,主要用于解耦。IOC是将创建的对象的控制权交给Spring框架进行管理。由Spring框架根据配置文件或注解等方式,创建Bean对象并管理各个Bean对象之间的依赖关系,使对象之间形成松散耦合的关系,实现解耦。
控制:指的是对象创建(实例化、管理)的权力
反转:控制权交给外部环境(Spring框架、IOC容器)
SpringIOC使用步骤:
- 创建类
- 将需要Spring管理的类,注入SpringIOC容器
<bean id="唯一标识" class="类的完全限定名称"></bean>
- 以解耦的方式获取JavaBean实例对象
- 加载Spring主配置文件,获取Spring核心对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
2. 获取JavaBean
Student student = (Student) applicationContext.getBean("student");
实现
在pom.xml中配置:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.25</version>
</dependency>
</dependencies>
项目结构如下图所示:
Controller层:
IUserController.java
package com.stringzhua.controller;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:28
* description:
*/
public interface IUserController {
public void add();
}
UserControllerImpl.java
package com.stringzhua.controller;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:29
* description:
*/
public class UserControllerImpl implements IUserController{
public void add() {
System.out.println("=====controller层的save()====");
}
}
Dao层:
IUserDao.java
package com.stringzhua.dao;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:37
* description:
*/
public interface IUserDao {
public void add();
}
UserDaoImpl.java
package com.stringzhua.dao;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:37
* description:
*/
public class UserDaoImpl implements IUserDao{
public void add() {
System.out.println("=====dao层的add()====");
}
}
POJO层:
Student.java
package com.stringzhua.pojo;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:21
* description:
*/
public class Student {
}
Service层:
IUserService.java
package com.stringzhua.service;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:38
* description:
*/
public interface IUserService {
public void add();
}
UserServiceImpl.java
package com.stringzhua.service;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:38
* description:
*/
public class UserServiceImpl implements IUserService{
public void add() {
System.out.println("=====service层的add()====");
}
}
测试类:
package com.stringzhua.test;
import com.stringzhua.controller.IUserController;
import com.stringzhua.dao.IUserDao;
import com.stringzhua.pojo.Student;
import com.stringzhua.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;
/**
* @Author Stringzhua
* @Date 2024/9/10 14:22
* description:
*/
public class Test01 {
public static void main(String[] args) {
//1.加载spring主配置文件获取ioc容器对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//2.获取javaBean
//默认为Object类型的对象,需要转换类型
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
IUserController controller = (IUserController) applicationContext.getBean("controller");
controller.add();
IUserService service = (IUserService) applicationContext.getBean("service");
service.add();
IUserDao dao = (IUserDao) applicationContext.getBean("dao");
dao.add();
Date date = (Date) applicationContext.getBean("date");
System.out.println(date);
}
}
两个Demo的对比:
SpringDI
SpringDI:依赖注入
DI(Dependency Inject,中文释义:依赖注入)
是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个Bean对象都要依赖IOC容器注入当前Bean对象所需要的另外一个Bean对象。
例如:在MyBatis整合Spring时,SqlSessionFactoryBean依赖IOC注入一个DataSource数据源Bean
SpringDI的实现方式:
- set注入
- 构造注入
- 注解注入
SpringDI支持的数据类型:
- 基本数据类型与String类型
- JavaBean对象
- 复杂类型(构造注入不支持)
DI实现步骤:
- 思考
- 提供对应方法(set) set(XXXXX)
- 配置
<property 属性名="属性值"></property>
属性:
name:属性名
ref:注入的值的引用
value:注入的值
DI实现步骤 (构造实现):
- 思考
- 提供对应的构造方法(构造)
- 配置
<constructor-arg 属性名="属性值"></constructor-arg>
属性:
name:属性名
type: 参数类型
index: 参数下标
ref:注入的值的引用
value:注入的值
总结IOC和DI
原来要对象,自己造自己用
现在要对象,容器造,容器拼一块,自己用
“Spring胶水框架”
set注入
在pom.xml中进行配置:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.25</version>
</dependency>
项目结构:
全部代码:
Controller层:
IUserController.java
package com.stringzhua.controller;
/**
* @Author Stringzhua
* @Date 2024/9/10 16:02
* description:
*/
public interface IUserController {
public void add();
}
UserControllerImpl.java
package com.stringzhua.controller;
import com.stringzhua.service.IUserService;
/**
* @Author Stringzhua
* @Date 2024/9/10 16:03
* description:
*/
public class UserControllerImpl implements IUserController {
IUserService service;
//di注入步骤1:提供set方法
public void setService(IUserService service) {
this.service = service;
}
public void add() {
System.out.println("==controller层的add方法==");
service.add();
}
}
Dao层:
IUserDao.java
package com.stringzhua.dao;
/**
* @Author Stringzhua
* @Date 2024/9/10 15:59
* description:
*/
public interface IUserDao {
public void add();
}
package com.stringzhua.dao;
/**
* @Author Stringzhua
* @Date 2024/9/10 16:00
* description:
*/
public class UserDaoImpl implements IUserDao{
public void add() {
System.out.println("=====Dao层的add方法===");
}
}
POJO层:
Student.java
package com.stringzhua.pojo;
/**
* @Author Stringzhua
* @Date 2024/9/10 15:54
* description:
*/
public class Student {
private String stuName;
private int stuAge;
//di步骤1:提供set方法
public void setStuName(String stuName) {
this.stuName = stuName;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
@Override
public String toString() {
return "Student{" +
"stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
'}';
}
}
Teacher.java
package com.stringzhua.pojo;
import java.util.*;
/**
* @Author Stringzhua
* @Date 2024/9/10 17:06
* description:
*/
public class Teacher {
private List mylist;
private Set myset;
private String[] myarray;
private Map mymap;
private Properties prop;
public void setMylist(List mylist) {
this.mylist = mylist;
}
public void setMyset(Set myset) {
this.myset = myset;
}
public void setMyarray(String[] myarray) {
this.myarray = myarray;
}
public void setMymap(Map mymap) {
this.mymap = mymap;
}
public void setProp(Properties prop) {
this.prop = prop;
}
@Override
public String toString() {
return "Teacher{" +
"mylist=" + mylist +
", myset=" + myset +
", myarray=" + Arrays.toString(myarray) +
", mymap=" + mymap +
", prop=" + prop +
'}';
}
}
Service层:
IUserService.java
package com.stringzhua.service;
/**
* @Author Stringzhua
* @Date 2024/9/10 16:01
* description:
*/
public interface IUserService {
public void add();
}
UserServiceImpl.java
package com.stringzhua.service;
import com.stringzhua.dao.IUserDao;
/**
* @Author Stringzhua
* @Date 2024/9/10 16:01
* description:
*/
public class UserServiceImpl implements IUserService {
IUserDao dao;
public void setDao(IUserDao dao) {
this.dao = dao;
}
public void add() {
System.out.println("==Service层的add方法==");
dao.add();
}
}
测试类:
Test.java
package com.stringzhua.test;
import com.stringzhua.controller.IUserController;
import com.stringzhua.pojo.Student;
import com.stringzhua.pojo.Teacher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author Stringzhua
* @Date 2024/9/10 15:57
* description:
*/
public class Test01 {
public static void main(String[] args) {
//1.获取Application对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取JavaBean
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
IUserController controller = (IUserController) applicationContext.getBean("controllerImpl");
controller.add();
Teacher teacher = (Teacher) applicationContext.getBean("teacher");
System.out.println(teacher);
}
}
实现:set注入基本数据类型与String
applicationContext.xml
<!-- set注入基本数据类型与String-->
<bean id="student" class="com.stringzhua.pojo.Student">
<property name="stuName" value="晞冉"></property>
<property name="stuAge" value="20"></property>
</bean>
//1.获取Application对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取JavaBean
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
实现:set注入javabean对象
applicationContext.xml
<!-- set注入JavaBean-->
<bean id="daoImpl" class="com.stringzhua.dao.UserDaoImpl"></bean>
<bean id="serviceImpl" class="com.stringzhua.service.UserServiceImpl">
<property name="dao" ref="daoImpl"></property>
</bean>
<bean id="controllerImpl" class="com.stringzhua.controller.UserControllerImpl">
<property name="service" ref="serviceImpl"></property>
</bean>
//1.获取Application对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取JavaBean
IUserController controller = (IUserController) applicationContext.getBean("controllerImpl");
controller.add();
实现:set注入复杂类型
applicationContext.xml
<!-- set注入复杂类型-->
<bean id="teacher" class="com.stringzhua.pojo.Teacher">
<property name="mylist">
<list>
<value>有何不可</value>
<value>断桥残雪</value>
<value>千百度</value>
<value>老古董</value>
<value>三尺</value>
</list>
</property>
<property name="myset">
<set>
<value>田晞冉</value>
<value>李芸芸</value>
<value>董万鹏</value>
<value>高夏斌</value>
</set>
</property>
<property name="myarray">
<array>
<value>雁塔区</value>
<value>莲湖区</value>
<value>长安区</value>
<value>长安区</value>
<value>高新区</value>
</array>
</property>
<property name="mymap">
<map>
<entry key="袁继峰" value="男"></entry>
<entry key="陈博文" value="男"></entry>
<entry key="郭忠航" value="男"></entry>
</map>
</property>
<property name="prop">
<props>
<prop key="王文茜">已毕业</prop>
<prop key="赵文瑜">未毕业,大四</prop>
<prop key="张玉婷">文科专业转码</prop>
</props>
</property>
//1.获取Application对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取JavaBean
Teacher teacher = (Teacher) applicationContext.getBean("teacher");
System.out.println(teacher);
构造注入:
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.25</version>
</dependency>
</dependencies>
项目结构:
全部代码:
Controller层:
IUserController.java
package com.stringzhua.controller;
/**
* @Author Stringzhua
* @Date 2024/9/10 18:00
* description:
*/
public interface IUserController {
public void add();
}
UserControllerImpl.java
package com.stringzhua.controller;
import com.stringzhua.service.IUserSerivce;
import com.stringzhua.service.UserServiceImpl;
/**
* @Author Stringzhua
* @Date 2024/9/10 18:01
* description:
*/
public class UserControllerImpl implements IUserController {
IUserSerivce serivce;
public UserControllerImpl() {
}
public UserControllerImpl(IUserSerivce serivce) {
this.serivce = serivce;
}
public void add() {
System.out.println("==UserController层的add方法==");
serivce.add();
}
}
Dao层:
IUser.java
package com.stringzhua.dao;
/**
* @Author Stringzhua
* @Date 2024/9/10 17:57
* description:
*/
public interface IUserDao {
public void add();
}
UserDaoImpl.java
package com.stringzhua.dao;
/**
* @Author Stringzhua
* @Date 2024/9/10 17:58
* description:
*/
public class UserDaoImpl implements IUserDao {
public void add() {
System.out.println("==UserDao层的add方法==");
}
}
POJO层:
Student.java
package com.stringzhua.pojo;
/**
* @Author Stringzhua
* @Date 2024/9/10 17:50
* description:
*/
public class Student {
private String stuName;
private int stuAge;
public Student() {
}
public Student(String stuName, int stuAge) {
this.stuName = stuName;
this.stuAge = stuAge;
}
@Override
public String toString() {
return "Student{" +
"stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
'}';
}
}
Service层;
IUserService.java
package com.stringzhua.service;
/**
* @Author Stringzhua
* @Date 2024/9/10 17:59
* description:
*/
public interface IUserSerivce {
public void add();
}
UserServiceImpl.java
package com.stringzhua.service;
import com.stringzhua.dao.IUserDao;
/**
* @Author Stringzhua
* @Date 2024/9/10 17:59
* description:
*/
public class UserServiceImpl implements IUserSerivce {
IUserDao dao;
public UserServiceImpl() {
}
public UserServiceImpl(IUserDao dao) {
this.dao = dao;
}
public void add() {
System.out.println("==UserSerivce层的add方法==");
dao.add();
}
}
Test:
test.java
package com.stringzhua.service;
import com.stringzhua.dao.IUserDao;
/**
* @Author Stringzhua
* @Date 2024/9/10 17:59
* description:
*/
public class UserServiceImpl implements IUserSerivce {
IUserDao dao;
public UserServiceImpl() {
}
public UserServiceImpl(IUserDao dao) {
this.dao = dao;
}
public void add() {
System.out.println("==UserSerivce层的add方法==");
dao.add();
}
}
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">
<!-- 构造注入基本类型与String-->
<!-- <bean id="student" class="com.stringzhua.pojo.Student">-->
<!-- <constructor-arg name="stuName" value="晞冉"></constructor-arg>-->
<!-- <constructor-arg name="stuAge" value="18"></constructor-arg>-->
<!-- </bean>-->
<!-- <bean id="student" class="com.stringzhua.pojo.Student">-->
<!-- <constructor-arg index="0" value="晞冉"></constructor-arg>-->
<!-- <constructor-arg index="1" value="18"></constructor-arg>-->
<!-- </bean>-->
<bean id="student" class="com.stringzhua.pojo.Student">
<constructor-arg type="java.lang.String" value="晞冉"></constructor-arg>
<constructor-arg type="int" value="18"></constructor-arg>
</bean>
<!-- ==构造注入javabean==-->
<bean id="daoImpl" class="com.stringzhua.dao.UserDaoImpl"></bean>
<bean id="serviceImpl" class="com.stringzhua.service.UserServiceImpl">
<constructor-arg name="dao" ref="daoImpl"></constructor-arg>
</bean>
<bean id="controllerImpl" class="com.stringzhua.controller.UserControllerImpl">
<constructor-arg name="serivce" ref="serviceImpl"></constructor-arg>
</bean>
</beans>
实现:构造注入基本类型与String类型
applicationContext.xml
<bean id="student" class="com.stringzhua.pojo.Student">
<constructor-arg name="stuName" value="晞冉"></constructor-arg>
<constructor-arg name="stuAge" value="18"></constructor-arg>
</bean>
<bean id="student" class="com.stringzhua.pojo.Student">
<constructor-arg index="0" value="晞冉"></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
</bean>
<bean id="student" class="com.stringzhua.pojo.Student">
<constructor-arg type="java.lang.String" value="晞冉"></constructor-arg>
<constructor-arg type="int" value="18"></constructor-arg>
</bean>
Test.java
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
实现:构造注入javabean对象
applicationContext.xml
<!-- <!– ==构造注入javabean==–>-->
<bean id="daoImpl" class="com.stringzhua.dao.UserDaoImpl"></bean>
<bean id="serviceImpl" class="com.stringzhua.service.UserServiceImpl">
<constructor-arg name="dao" ref="daoImpl"></constructor-arg>
</bean>
<bean id="controllerImpl" class="com.stringzhua.controller.UserControllerImpl">
<constructor-arg name="serivce" ref="serviceImpl"></constructor-arg>
</bean>
Test.java
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// Student student = (Student) applicationContext.getBean("student");
// System.out.println(student);
IUserController controller = (IUserController) applicationContext.getBean("controllerImpl");
controller.add();
Spring常见面试题
Spring 框架的基本理解
- 关键字: 核心思想IOC\AOP、作用(解耦、简化),简单描述框架组成
- Spring 框架是一款轻量级的开发框架,核心思想是 IOC(控制反转)和 AOP(面向切面编程) 为java 应用程序开发提供组件管理服务,用于组件之间的解耦,以及简化第三方JavaEE中间件技术的使用(jms、任务调度、缓存、orm 框架),是一个基础架构型的开发框架
- Spring框架包括: IOC容器、Validation 数据校验、AOP面向切面编程、Transactions 事务管理、SpringJDBC 、Spring MVC框架、以及各类第三方JavaEE 中间件技术集成
Spring 框架由哪些模块组成?
- 关键字: 官方文档描述,由7个模块组成
- Spring framwork 根据官方文档的描述,主要包括以下常用5个模块:
- Core:核心模块 包括: IoC Container(loc容器),Events(事件通知机制),Resources(资源加载机制),118n(国际化),Validation(数据校验),Data Binding(数据绑定),Type Conversion(类型转换),spEl(spring表达式),AOP(面向切面编程);
- Testing:测试模块 包括: Mock Objects(测试模拟对象),TestContext Framework(测试框架),Spring MVC Test(用于测试Spring MVC),WebTestClient(用于测试WebClient 、Restful、Webflux等)
- Data Access:数据访问模块 包括:Transactions (事务管理),Dao Support (统一的 Data Access Object DAO 模式封装),jdbc(spring 对于 jdbc 的操作封装),O/R Mapping( spring 对于对象关系映射框架的封装,例如 hibernate 等框架)等;
- Web servlet:基于servlet的web应用开发 包括: Spring Mvc( Spring 基于 Mvc 模式设计封装的Web 框架), WebSocket(spring集成 websocket,websocket 是一个服务器与客户端双向通信的技术)等;
- Integration:企业级系统集成模块(不同系统之间的交互集成) 包括∶ remoting(spring 用于在分布式系统中进行远程服务调用的通讯框架)
Spring IOC的理解
- 关键字: IOC 名词解释,作用是解耦,使用IOC容器管理项目组件之间的耦合关系
- IOC(Inversion of control,中文释义:控制反转)是 Spring 框架的核心思想之一,主要用于解耦。IOC 是指将创建对象的控制权转移给 Spring 框架进行管理。由spring框架根据配置 文件或注解等方式,创建Bean对象并管理各个 Bean 对象之间的依赖关系。使对象之间形成松散耦合的关系,实现解耦 。
- 控制:指的是对象创建(实例化、管理)的权力
- 反转:控制权交给外部环境( Spring 框架、IoC 容器 )
Spring IOC容器的理解
- 关键字: IOC 容器的作用、存储形式、初始化过程
- IOC 通常被理解为 IOC Container 容器,IOC 容器其实就是一个 Map,key 是每个bean对象的ID,value 是 bean 对象本身。IOC 容器负责创建 bean 对象并管理 bean 的生命周期。并且根据配置好配置文件或注解,管理 ioc 容器中的每个bean,以及根据bean之间的依赖关系,完成bean之间的注入
- IOC 容器属于Spring core模块,用来创建和管理bean,默认使用单例的方式将bean存储在 DefaultListableBeanFactory类的beanDefinitionMap中(一个 ConcurrentHashMap 类型的Map集合)
- IOC 容器使用 ConcurrentHashMap 集合存储了 BeanDefinition 对象,该对象封装了 Spring 对一个 Bean 所有配置信息,包括:类名,属性,构造方法参数,依赖,是否延迟加载,是否是单例等配置信息
Spring DI的理解
- DI( dependecy inject,中文释义:依赖注入)是对 IOC 概念的不同角度的描述,是指应用程序在运行时,每一个 bean 对象都依赖 IOC 容器注入当前 bean 对象所需要的另外一个 bean 对象。(例如在 mbatis整合 spring 时,SqlSessionFactoryBean 依赖 ioc 容器注入一个 DataSource 数据源 bean )