(一)Spring工厂的底层实现原理(简易版)&理解Spring三大核心思想之一:IOC思想及使用

Spring不是替换某一层次的技术替换,而是统筹有全局,将当前的技术整合进行整合管理,柔和在一起

  • 致力于javaEE(企业级)轻量级解决方案

轻量级解决方案

提供一个以简单的,统一的,高效的方式构造整个应用,并且可以将单层框架

以最佳的组合柔和在一起建立一个连贯的体系,Struts2+Spring(中间件 中介)+Mybatis

  • 整合设计模式
  1. 工厂

  2. 代理

  3. 模板

  4. 策略

  5. 单例

  • Spring总结思路图

3、Spring如何对项目进行管理?

  • 核心作用:用Spring来管理组件,负责组件的创建,管理,销毁

  • Spring框架用来管理(创建,使用,销毁)组件 ,由于Spring框架可以帮我们生成项目中组件对象,因此Spring是一个工厂/容器

  • 注意:Spring一般不管理实体类对象(entity)

  • 传统的使用JVM进行垃圾回收销毁,Spring自动进行销毁

二、工厂设计模式手写一个Spring

=====================================================================================

  • 设计模式
  1. 广义概念

面向对象设计中,解决特定问题的经典代码

  1. 狭义概念

GOF4人帮定义的23种设计模式:工厂、适配器、装饰器、门面、代理、模板…

1、什么是工厂设计模式

  1. 概念:通过工厂类,创建对象

User user = new User();

UserDAO userDAO = new UserDAOImpl();

  1. 好处:解耦合

耦合:指定是代码间的强关联关系,一方的改变会影响到另一方

问题:不利于代码维护

简单:把接口的实现类,硬编码在程序中

UserService userService = new UserServiceImpl();

2、简单的工厂设计

  • 原始的方法:硬编码,耦合

  • 对象的创建方式:

对象的创建方式:

  1. 直接调用构造方法 创建对象 UserService userService = new UserServiceImpl();

  2. 通过反射的形式 创建对象 解耦合

Class clazz = Class.forName(“com.tjcu.factory.service.UserService”);

UserService userService = (UserService)clazz.newInstance();

  • new创建对象

/**

  • @author 王恒杰

  • @version 1.0

  • @date 2021/11/9 13:49

  • @email 1078993387@qq.com

  • @Address 天津

  • @Description: 直接调用构造方法 创建对象

*/

public class BeanFactory {

public static UserService getUserService(){

return new UserServiceImpl();

}

  • 通过反射创建

public static UserService getUserService(){

UserService userService =null;

try {

Class clazz = Class.forName(“com.tjcu.factory.service.impl.UserServiceImpl”);

userService = (UserService) clazz.newInstance();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return userService;

}

  • 优化反射的方式
  1. 创建application.properties

  2. application.properties文件加载进工厂里面

/**

  • @author 王恒杰

  • @version 1.0

  • @date 2021/11/9 13:49

  • @email 1078993387@qq.com

  • @Address 天津

  • @Description:通过反射的形式 创建对象 解耦合

*/

public class BeanFactory {

private static Properties properties = new Properties();

static {

//第一步 获得IO输入流

InputStream inputStream = BeanFactory.class.getResourceAsStream(“/application.properties”);

//第二步 文件内容 封装Properties集合中key=UserService ,value=com.tjcu.factory.service.impl.UserServiceImpl

try {

properties.load(inputStream);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

  • 对象的创建方式:

    1. 直接调用构造方法 创建对象 UserService userService = new UserServiceImpl();
    1. 通过反射的形式 创建对象 解耦合
  • Class clazz = Class.forName(“com.tjcu.factory.service.UserService”);

  • UserService userService = (UserService)clazz.newInstance();

*/

public static UserService getUserService() {

UserService userService = null;

try {

Class clazz = Class.forName(properties.getProperty(“userService”));

userService = (UserService) clazz.newInstance();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return userService;

}

}

  • 测试

3、通用工厂的设计

  • 问题:简单工厂会存在大量的代码冗余

  • 通用工厂代码

/**

  • @author 王恒杰

  • @version 1.0

  • @date 2021/11/9 13:49

  • @email 1078993387@qq.com

  • @Address 天津

  • @Description:通过反射的形式 创建对象 解耦合

*/

public class BeanFactory {

private static Properties properties = new Properties();

static {

//第一步 获得IO输入流

InputStream inputStream = BeanFactory.class.getResourceAsStream(“/application.properties”);

//第二步 文件内容 封装Properties集合中key=UserService ,value=com.tjcu.factory.service.impl.UserServiceImpl

try {

properties.load(inputStream);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

  • 对象的创建方式:

    1. 直接调用构造方法 创建对象 UserService userService = new UserServiceImpl();
    1. 通过反射的形式 创建对象 解耦合
  • Class clazz = Class.forName(“com.tjcu.factory.service.UserService”);

  • UserService userService = (UserService)clazz.newInstance();

*/

public static Object getBean(String key){

Object o=null;

try {

Class clazz= Class.forName(properties.getProperty(key));

o= clazz.newInstance();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return o;

}

}

  • 测试

/**

  • 用来测试工厂解耦合的操作

*/

@Test

public void loginTest(){

//UserServiceImpl userService = new UserServiceImpl();

UserService userService = (UserService) BeanFactory.getBean(“userService”);

User user = new User();

user.setUsername(“王恒杰”);

user.setPassword(“123456”);

User login = userService.login(user.getUsername(), user.getPassword());

System.out.println(login);

}

}

4、通用工厂的使用方式

  1. 定义类型 (类)

  2. 通过配置文件的配置告知工厂(applicationContext.properties)

key = value

  1. 通过工厂获得类的对象

Object ret = BeanFactory.getBean(“key”)

5、工厂总结

Spring本质:工厂 ApplicationContext(应用程序上下文) (applicationContext.xml)

三、第一个Spring程序

================================================================================

1、软件版本

  1. JDK1.8+

  2. Maven3.5+

  3. IDEA2018+

  4. SpringFramework 5.1.4

官方网站 www.spring.io

2、环境搭建

  • Spring的jar包

#设置pom 依赖

org.springframework

spring-context

5.1.4.RELEASE

  • Spring相关依赖

org.springframework

spring-core

4.3.2.RELEASE

org.springframework

spring-beans

4.3.2.RELEASE

org.springframework

spring-web

4.3.2.RELEASE

org.springframework

spring-expression

4.3.2.RELEASE

org.springframework

spring-aop

4.3.2.RELEASE

org.springframework

spring-context

4.3.2.RELEASE

org.springframework

spring-context-support

4.3.2.RELEASE

org.springframework

spring-aspects

4.3.2.RELEASE

org.springframework

spring-jdbc

4.3.2.RELEASE

3、Spring配置文件创建

  1. bean标签负责组件对象的管理,一个bean标签只负责一个组件的管理,

  2. class:要管理的组件,java类的全限定名 包名.类名

  3. id: 组件对象在工厂中的唯一标识

建议命名规则:

(1)存在接口: 接口首字母小写

(2)没有接口:类名首字母小写

4、测试(所有错误:从下往上看)

通过工厂获取组件对象

//1.启动工厂 参数:工厂Spring配置文件的位置 路径 文件路径用/

Application ctx=new ClassPathXmlApplicationContext(“init/spring.xml”);

//2、获取组件对象 参数:组件对象在工厂中的唯一标识

UserDao userDao=(UserDao)ctx.getBean(“aa”);

//3.调用方法

userDao.add(“王恒杰”);

5、Spring核心API之ApplicationContext

  • ApplicationContext

作用:Spring提供的ApplicationContext这个⼯⼚,⽤于对象的创建

好处:解耦合

  • ApplicationContext接口类型

接⼝:屏蔽实现的差异

⾮web环境 : ClassPathXmlApplicationContext (main junit)

web环境 : XmlWebApplicationContext

  • 重量级资源

ApplicationContext⼯⼚的对象占⽤⼤量内存。

不会频繁的创建对象 : ⼀个应⽤只会创建⼀个⼯⼚对象。

ApplicationContext⼯⼚:⼀定是线程安全的(多线程并发访问)

四、Spring的核心思想之IOC

====================================================================================

1、Spring细节分析

  • 名词解释

Spring⼯⼚创建的对象,叫做bean或者组件(componet)

  • Spring⼯⼚的相关的⽅法

//通过这种⽅式获得对象,就不需要强制类型转换

Person person = ctx.getBean(“person”, Person.class);

System.out.println("person = " + person);

//当前Spring的配置⽂件中 只能有⼀个<bean class是Person类型

Person person = ctx.getBean(Person.class);

System.out.println("person = " + person);

//获取的是 Spring⼯⼚配置⽂件中所有bean标签的id值 person person1

String[] beanDefinitionNames = ctx.getBeanDefinitionNames();

for (String beanDefinitionName : beanDefinitionNames) {

System.out.println("beanDefinitionName = " +beanDefinitionName);

}

//根据类型获得Spring配置⽂件中对应的id值

String[] beanNamesForType = ctx.getBeanNamesForType(Person.class);

for (String id : beanNamesForType) {

System.out.println("id = " + id);

}

//⽤于判断是否存在指定id值得bean

if (ctx.containsBeanDefinition(“a”)) {

System.out.println("true = " + true);

}else{

System.out.println("false = " + false);

}

//⽤于判断是否存在指定id值得bean

if (ctx.containsBean(“person”)) {

System.out.println("true = " + true);

}else{

System.out.println("false = " + false);

}

  • Spring的核心思想

#1. IOC:控制反转|翻转控制

把对象的创建,赋值,管理工作都交给代码之外的容器实现,

也就是对象的创建是有其它外部资源完成。

#2. AOP 面向切面编程

2、IOC 思想:翻转控制

(1)什么是IOC控制反转
  • IOC: inversion of Controll 翻转控制,控制反转

  • 控制反转:控制权力的反转

将原有手工通过new关键字创建对象的权力,反转给Spring负责,由Spring负责对象的创建

  1. 控制: 创建对象,对象的属性赋值,对象之间的关系管理。

  2. 反转: 把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。

由容器代替开发人员管理对象。创建对象,给属性赋值。

  1. 正转:由开发人员在代码中,使用new 构造方法创建对象, 开发人员主动管理对象。

public static void main(String args[]){

// 在代码中, 创建对象。–正转。

Student student = new Student();

}

4.容器:是一个服务器软件, 一个框架(spring)

5.问题:未来在开发过程中,是不是所有的对象,都会交给Spring⼯⼚来创建呢?

回答:理论上 是的,但是有特例 :实体对象(entity)是不会交给Spring创建,它是由持久层

框架进⾏创建。

(2)为什么要使用 ioc ?

目的就是减少对代码的改动, 也能实现不同的功能。 实现解耦合。

(3)java中创建对象的方式有哪些?
  1. 构造方法 , new Student()

  2. 反射

  3. 序列化

  4. 克隆

  5. ioc :容器创建对象

  6. 动态代理

(4)案例
  • UserDao

public interface UserDao {

public void add(String name);

}

  • UserDaoImpl

public class UserDaoImpl implements UserDao{

@Override

public void add(String name) {

System.out.println(name+“被添加进数据库了!”);

}

}

  • Spring配置文件
<?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 思想:翻转控制 测试类

*/

@Test

public void add(){

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(“/init/Spring.xml”);

UserDao userDao = (UserDao) ctx.getBean(“userDao”);

userDao.add(“王恒杰”);

}

(5)为什么使用DI(依赖注入)
  • 不通过new创建对象的容器除了Spring还有

servlet

1: 创建类继承HttpServelt

2: 在web.xml 注册servlet , 使用

myservlet

com.bjpwernode.controller.MyServlet1

  1. 没有创建 Servlet对象, 没有 MyServlet myservlet = new MyServlet()

  2. Servlet 是Tomcat服务器它能你创建的。 Tomcat也称为容器

Tomcat作为容器:里面存放的有Servlet对象, Listener , Filter对象

👨‍💻注意 :因为ioc不是Spring独有(通过手工new创建对象交给Spring创建对象),所以提出新的概念:DI(依赖注入)

  1. 将原来手工new 创建对象交给Spring创建对象

  2. 将另外一个组件作为当前组件的成员变量,进行依赖注入

3、DI:依赖注入

  • spring是一个容器,管理对象,给属性赋值, 底层是反射创建对象。

  • spring-context: 是ioc功能的,创建对象的。

  • 基于IOC提出的思想:DI (dependency injection 依赖注入 )

  • 依赖的概念: 在一个组件需要另外一个组件,将另外一个组件作为这个组件的成员变量(没有注入

  • 注入:因为将另外一个组件作为这个组件的成员变量,但是这个成员变量是空的,我们将所依赖的成员变量赋值,就是注入 (提供set方法),在工厂中进行注入

  • 为依赖的成员变量进行注入(赋值)

name:成员变量名字

赋值:依赖的组件是工厂中另外一个组件,需要使用ref进行引用

ref:引用 值:依赖组件的唯一标识

【案例】
  • UserDao

public interface UserDao {

public void add(String name);

}

  • UserDaoImpl

public class UserDaoImpl implements UserDao {

@Override

public void add(String name) {

System.out.println(name+“Dao层被添加进数据库了!”);

}

}

  • UserService

public interface UserService {

public void add(String name);

}

  • UserServiceImpl【重点】

/**

  • @author 王恒杰

  • @version 1.0

  • @date 2021/11/10 14:27

  • @email 1078993387@qq.com

  • @Address 天津

  • @Description:

*/

public class UserServiceImpl implements UserService {

/**

  • 在UserService组件需要UserDAO组件,我们可以将UserDao组件当做成员变量

*/

private UserDao userDao;

@Override

public void add(String name) {

System.out.println(name+“实现了IOC:翻转控制,原先手工new创建对象现在交给Spring创建对象了”);

userDao.add(name);

}

/**

  • 为userdao提供set方法用于依赖注入

  • @param userDao

*/

public void setUserDao(UserDao userDao) {

this.userDao = userDao;

}

}

  • Spring配置文件

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

总的来说,面试是有套路的,一面基础,二面架构,三面个人。

最后,小编这里收集整理了一些资料,其中包括面试题(含答案)、书籍、视频等。希望也能帮助想进大厂的朋友

三面蚂蚁金服成功拿到offer后,他说他累了

三面蚂蚁金服成功拿到offer后,他说他累了

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

  • @Address 天津

  • @Description:

*/

public class UserServiceImpl implements UserService {

/**

  • 在UserService组件需要UserDAO组件,我们可以将UserDao组件当做成员变量

*/

private UserDao userDao;

@Override

public void add(String name) {

System.out.println(name+“实现了IOC:翻转控制,原先手工new创建对象现在交给Spring创建对象了”);

userDao.add(name);

}

/**

  • 为userdao提供set方法用于依赖注入

  • @param userDao

*/

public void setUserDao(UserDao userDao) {

this.userDao = userDao;

}

}

  • Spring配置文件

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-VPSn3n4d-1712544326412)]

[外链图片转存中…(img-CGHiyATi-1712544326413)]

[外链图片转存中…(img-ggFTOE9b-1712544326413)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

总的来说,面试是有套路的,一面基础,二面架构,三面个人。

最后,小编这里收集整理了一些资料,其中包括面试题(含答案)、书籍、视频等。希望也能帮助想进大厂的朋友

[外链图片转存中…(img-SBtS0U66-1712544326413)]

[外链图片转存中…(img-zvS2WNPy-1712544326413)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值