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 configurationPUBLIC "-//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;@Beforepublic 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();}}@Afterpublic void afterMethod() {sqlSession.close();}@Testpublic void show1() throws Exception {studentmapper.add(new Student("猫猫", "千逐", 18));studentmapper.add(new Student("田欣怡", "晞苒", 22));}@Testpublic 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对应的valueString 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;}@Overridepublic 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;}@Overridepublic 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.获取JavaBeanStudent 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;}@Overridepublic 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 )