spring原理

Spring IOC的底层实现原理

喜夏-厌秋 提交于 2019-12-05 23:44:52
PS:模块之间的相互依赖叫做耦合 传统方式的开发 UserService us=new UserService();       ||       v  面向接口编程 UserService us=new UserServiceImpl();       ||       v  ocp原则:open-close原则,对程序拓展是open的,对修改程序代码是close。尽量做到不修改程序的源码,实现对程序的拓展       ||       v      工厂模式 来源: https://www.cnblogs.com/yihuqingjiu/p/11950950.html

模拟spring IOC 实现

旧巷老猫 提交于 2019-12-05 18:18:01
利用java的反射和动态代理实现IOC 在 Java 中,其反射和动态代理机制极其强大,我们可以通过其反射机制在运行时获取信息。而代理是一种基本的设计模式,它是一种为了提供额外的或不同的操作而插入到真实对象中的某个对象。而 Java 的动态代理在代理上更进一步,既能动态的创建代理对象,又能动态的调用代理方法。 Java 的反射和动态代理机制,使 Java 变得更加强大。 Spring 框架这几年风头正劲,虽然使用者众多,但真正了解其内部实现原理的朋友却并不是很多。其实,了解它的内部实现机制和设计思想是很有必要的大家都知道, Spring 框架的 IOC 和 AOP 部分功能强大,很值得我们学习。那么让我们在这两篇文章中分别详细的学习 IOC 和 AOP 的实现吧。 在本文中,主要讲述的是用 Java 的反射机制实现 IOC 。下面,让我们开始 IOC 之旅吧! 一. Java 反射机制概述与初探 Java 的反射机制是 Java 语言的一个重要特性, Java 具有的比较突出的动态机制就是反射( reflection )。通过它,我们可以获取如下信息: 1) 在运行时判断任意一个对象所属的类; 2) 在运行时获取类的对象; 3) 在运行时获得类所具有的成员变量和方法等。 下面让我们通过调用一个 Java Reflection API 的演示实例来见识一下反射机制的强大。 首先在

Spring事物的传播

醉酒当歌 提交于 2019-12-05 17:08:25
spring的事物对于同一个类内部调用是不会生效的。 比如一个ServiceA,里面有个方法x()和y()。其中x没有配置事物,而y配置的有实物。如果是一个没有是一个没有事物的ServiceB调用了ServiceA的x方法,而在x里面直接通过this.y()的方式调用y方法。那么y是不会有实物的,就算配置成PROPAGATION_REQUIRED 也是不会有事物的。 反之,如果是没有事物的ServiceB先调用的ServiceA的y,而y又内部调用x这时候是有事物的。 原理很简单,只有被spring托管的调用方式它才能在外层封装事物。 execution(* com.aaa.someDao.*(..)) 第一个* 号表示任意返回值,后面的*(..)表示任意参数 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起

Spring循环依赖的三种方式以及解决办法

点点圈 提交于 2019-12-05 11:30:29
https://www.cnblogs.com/liuqing576598117/p/11227007.html Spring循环依赖的三种方式以及解决办法 一. 什么是循环依赖? 循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如下图: 注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。 Spring中循环依赖场景有: (1)构造器的循环依赖 (2)field属性的循环依赖 其中,构造器的循环依赖问题无法解决,只能拋出BeanCurrentlyInCreationException异常,在解决属性循环依赖时,spring采用的是提前暴露对象的方法。 二. 怎么检测是否存在循环依赖 检测循环依赖相对比较容易,Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。 三、三种循环依赖 1:构造器的循环依赖。【这个Spring解决不了】   Spring容器会将每一个正在创建的Bean 标识符放在一个“当前创建Bean池”中,Bean标识符在创建过程中将一直保持在这个池中,因此如果在创建Bean过程中发现自己已经在“当前创建Bean池

Spring 依赖注入的方法(基于xml配置)

心已入冬 提交于 2019-12-05 07:02:54
Spring 依赖注入的方法(基于xml配置) 前言 Spring依赖注入的方法有三种: 属性注入(setter方法注入) 构造函数注入(入参方式有所差异) 工厂方法注入(静态方法和非静态方法) Spring依赖注入原理:是利用Java的反射机制 注: Spring可以注入类实现所需要的外部资源,实例主要注入的是属性,所有的实例都可以在idea上运行测试,文章末尾附了一些maven工程结构和配置 属性注入(set注入) 属性注入条件:类中有默认的构造方法(即无参构造方法),有属性对应的setter方法。 实例:(在Animal类中生成setter方法) public class Animal { private String name; private String food; public void printAnlimal(){ System.out.println(name + "吃" + food); } /*java类中如果没有构造方法会自动生成默认的无参构造方法, 如果有带参数 的构造方法,Java类就不会自动生成默认构造方法,就需要手动创建无参构造方法*/ public void setName(String name) { this.name = name; } public void setFood(String food) { this.food = food;

SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - 自定义Servlet、Filter、Listener是如何注册到Tomcat容器中的?(SpringBoot实现SpringMvc的原理)

浪子不回头ぞ 提交于 2019-12-05 06:27:25
上一篇我们讲了SpringBoot中Tomcat的启动过程,本篇我们接着讲在SpringBoot中如何向Tomcat中添加Servlet、Filter、Listener 自定义Servlet、Filter、Listener Spring容器中声明ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean @Bean public ServletRegistrationBean customServlet() { return new ServletRegistrationBean(new CustomServlet(), "/custom"); } private static class CustomServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("receive by custom servlet"); } } 先自定义一个 Servlet,重写 service实现自己的业务逻辑

javassist 版本导致ClassNotFoundException: javassist.ClassPath异常

柔情痞子 提交于 2019-12-05 04:28:52
1、异常描述 使用Dubbo时,引入了javassist导致出现了ClassNotFoundException: javassist.ClassPath异常,因为此异常网上资料较少,特分享出来供大家脱坑: 服务启动后报错: message: Context initialization failed (o.s.web.context.ContextLoader:350) [localhost-startStop-1] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.wesd.hrhx.service.dubbo.DebtDubboService': Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError. 2、异常定位 从错误信息中可看出,错误来源于Spring注入DebtDubboService出错,我们继续往下找具体的原因: Caused by: java.lang.NoClassDefFoundError: javassist/ClassPath at java.lang.Class.forName0(Native

SpringBoot 源码解析 (六)----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)

家住魔仙堡 提交于 2019-12-05 04:00:19
Spring Boot默认使用Tomcat作为嵌入式的Servlet容器,只要引入了spring-boot-start-web依赖,则默认是用Tomcat作为Servlet容器: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> Servlet容器的使用 默认servlet容器 我们看看spring-boot-starter-web这个starter中有什么 核心就是引入了tomcat和SpringMvc,我们先来看tomcat Spring Boot默认支持Tomcat,Jetty,和Undertow作为底层容器。如图: 而Spring Boot默认使用Tomcat,一旦引入spring-boot-starter-web模块,就默认使用Tomcat容器。 切换servlet容器 那如果我么想切换其他Servlet容器呢,只需如下两步: 将tomcat依赖移除掉 引入其他Servlet容器依赖 引入jetty: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web<

spring --读写分离

*爱你&永不变心* 提交于 2019-12-05 03:39:32
实现流程 1.ssm基本流程 1.1 一个http请求,被springMVC的DispatcherServlet拦截,然后交给HandleRequest处理。 1.2 HandleRequest调用HandlerMapping与HandlerAdapter两个类,去匹配controller上的路径。 1.3 一旦匹配上,就执行该路径对应的方法。 1.4 controller层只是起一个控制作用,实际的业务处理交给service实现层。 1.5 实现层处理完数据,将结果返回给controller层。 这是一个基本的ssm流程 2.实现读写分离 2.1 配置一个动态数据源切面,将该切面添加到service上。 2.2 一旦有请求进来,执行到service层,该切面进行拦截,能够获取到请求方法的名称和参数。 2.3 这里我们只需要方法名称就够了,实际上这里拿到的方法名称与请求参数可以做缓存(即是spring缓存原理)。该切面完成的功能是:根据执行方法名称判断应该走读库还是走写库,这里返回的是一个标记(读库还是写库的标记)。 2.4 接着有一个动态数据源的bean,该bean继承spring的AbstractRoutingDataSource类,并且覆写该类的determineCurrentLookupKey方法,返回读写库标记。同时该bean配置在spring-mybatis

Spring/Spring-Boot 学习2 入门知识

天涯浪子 提交于 2019-12-05 02:38:27
在Spring/Spring-Boot的入门上我绕了很多弯路,我绕过的一个典型的弯路是: 找一个Spring-Boot的入门案例,下载代码跟着跑了一遍,跑通之后确不能理解代码,尤其是各种配置文件以及注解让我难以理解这个程序究竟是怎么跑起来的。@Autowired, @Controller这些注解到底是什么意思,它的工作流程是怎样的? 我怀疑自己是注解相关的知识没有学好,于是往下挖注解的工作原理-->动态代理机制-->反射-->类加载过程-->类加载器的工作原理。这样一套走下来之后,即使我懵懵懂懂明白了类加载器、反射、动态代理、注解, 我还是不能看懂spring的这些注解是怎么工作的,也不知道怎么去实际使用他们。 很多的入门教程,给出了很多具体的操作,但是并没有告诉我们为什么spring要用这个注解,这个注解用了之后他会有什么作用,以及这些注解的工作流程(我指的是使用流程不是底层的实现原理)。 下面是我自己的一些学习反思。 首先我们从最基本的需求讲起。 java是面向对象的语言,每个对象都可以绑定一定的操作,通过将多个对象组合,我们可以完成一个任务所需要的所有操作。 举个例子,假设我们的任务是接收用户对 localhost:8080/user 这个链接的get请求,返回给用户浏览器一个含有用户数据的json数据串 “{"name":"bob"}”。我们把这个任务分成到多个对象去完成