挂面01

1.DNS原理及其解析过程

为什么?
网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址的,所以计算机在网络上进行通讯时只能识别如“202.96.134.133”之类的IP地址,而不能认识域名。
过程

1) 浏览器缓存  
当用户通过浏览器访问某域名时,浏览器首先会在自己的缓存中查找是否有该域名对应的IP地址
(若曾经访问过该域名且没有清空缓存便存在); 
2) 系统缓存  
当浏览器缓存中无域名对应IP则会自动检查用户计算机系统Hosts文件DNS缓存是否有该域名对应IP;  
Linux下面的位置/etc/hosts windows下C:\Windows\System32\drivers\etc
3) 路由器缓存  
当浏览器及系统缓存中均无域名对应IP则进入路由器缓存中检查,以上三步均为客服端的DNS缓存;  
4) ISP(互联网服务提供商)DNS缓存  
当在用户客服端查找不到域名对应IP地址,则将进入ISP DNS缓存中进行查询。
比如你用的是电信的网络,则会进入电信的DNS缓存服务器中进行查找;  
5) 根域名服务器  
当以上均未完成,则进入根服务器进行查询。全球仅有13台根域名服务器,
1个主根域名服务器,其余12为辅根域名服务器。
根域名收到请求后会查看区域文件记录,若无则将其管辖范围内顶级域名(如.com)服务器IP告诉本地DNS服务器;  
6) 顶级域名服务器  
顶级域名服务器收到请求后查看区域文件记录,若无则将其管辖范围内主域名服务器的IP地址告诉本地DNS服务器;  
7) 主域名服务器  
主域名服务器接受到请求后查询自己的缓存,如果没有则进入下一级域名服务器进行查找,
并重复该步骤直至找到正确纪录;  
8)保存结果至缓存  
本地域名服务器把返回的结果保存到缓存,以备下一次使用,
同时将该结果反馈给客户端,客户端通过这个IP地址与web服务器建立链接

DNS几级域名?

www.   zhihu.  com     .
三级域 二级域 顶级域 根域
www.   zhihu. com.   cn      .
四级域 三级域 二级域 顶级域 根域
说明:根域是后面的点(.)

2.使用Spring框架的好处

轻量:Spring 是轻量的,基本的版本大约2MB。

控制反转IOC:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,
而不是创建或查找依赖的对象们。

面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

容器:Spring 包含并管理应用中对象的生命周期和配置。

MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。

事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。

异常处理:Spring 提供方便的API把具体技术相关的异常
(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。

3.spring ioc原理

IOC控制反转:说的是创建对象实例的控制权从代码控制剥离到IOC容器控制,实际上就是我们现在说的第三方

Spring容器高层视图

Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系。为上层应用提供准备就绪的运行环境。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。
IOC容器设计中,两个主要的接口
BeanFactory
ApplicationContext
我们一般称BeanFactory为IoC容器,而称ApplicationContext为应用上下文或Spring容器。
对于BeanFactory 和 ApplicationContext的用途:
1.BeanFactory是Spring框架的基础设施,面向Spring本身
它是一个类的通用工厂,可以创建并管理各种类的对象。
这些被创建和管理的对象,并无特别之处,仅仅是一个POJO。
BeanFactory的主要方法是 getBean(String beanName). 该方法从容器中返回特定名称的Bean
2.ApplicationContext面向使用Spring框架的开发者,直接使用Application而非底层的BeanFactory.

4.Java反射机制在Spring IOC中的应用

IOC底层实现的原理(反射)
在Spring的配置文件中,经常看到如下配置
<bean id="courseDao" class="com.qcjy.learning.Dao.impl.CourseDaoImpl"></bean>
Spring是怎么帮我们实例化对象,并且放到容器中去了?
对,就是通过反射.

伪代码
//解析<bean .../>元素的id属性得到该字符串值为“courseDao”
String idStr = "courseDao";
//解析<bean .../>元素的class属性得到该字符串值为“com.qcjy.learning.Dao.impl.CourseDaoImpl”
String classStr = "com.qcjy.learning.Dao.impl.CourseDaoImpl";
//利用反射知识,通过classStr获取Class类对象
Class<?> cls = Class.forName(classStr);
//实例化对象
Object obj = cls.newInstance();
//container表示Spring容器
container.put(idStr, obj);

通过解析xml文件,获取到id属性和class属性里面的内容,利用反射原理Class.froName()获取到配置里面类的实例对象,存入到Spring的bean容器中。
当一个类里面需要应用另一类的对象时,Spring的配置如下所示:

<bean id="courseService" class="com.qcjy.learning.service.impl.CourseServiceImpl">
     <!-- 控制调用setCourseDao()方法,将容器中的courseDao bean作为传入参数 -->
     <property name="courseDao" ref="courseDao"></property>
</bean>

伪代码

//解析<property .../>元素的name属性得到该字符串值为“courseDao”
String nameStr = "courseDao";
//解析<property .../>元素的ref属性得到该字符串值为“courseDao”
String refStr = "courseDao";
//生成将要调用setter方法名
String setterName = "set" + nameStr.substring(0, 1).toUpperCase()
        + nameStr.substring(1);
//获取spring容器中名为refStr的Bean,该Bean将会作为传入参数
Object paramBean = container.get(refStr);
//获取setter方法的Method类,此处的cls是刚才反射代码得到的Class对象
Method setter = cls.getMethod(setterName, paramBean.getClass());
//调用invoke()方法,此处的obj是刚才反射代码得到的Object对象
setter.invoke(obj, paramBean);

只要在代码或配置文件中看到类的完整路径(包.类),其底层原理基本上使用的就是Java的反射机制

5.可以自己写一个spring IOC

1.假设有一个Student.java

 public class Student {  
  private int id;  
  private String name;  
  ******************set、get方法省略  
}

2.因为spring提倡的就是面向接口编程,所以先定义接口StudentDaoStudentService ,让我们的具体实现类实现接口,里面假设有一个添加学生的方法
3.实现类StudentDaoImp implements StudentDaoStudentServiceImpimplements StudentService`

public class StudentDaoImp implements StudentDao {  
public void add(Student stu) {  
System.out.println("stu is saved");  
}  
}


public class StudentServiceImp implements StudentService {  
StudentDao stuDao=null;  
public StudentDao getStuDao() {  
return stuDao;  
}  
public void setStuDao(StudentDao stuDao) {  
this.stuDao = stuDao;  
}  
@Override  
public void add(Student stu) {  
stuDao.add(stu);  
}  
}

模拟spring中的IOC功能,所以在此我们一样要在service层中定义dao的实例,当然不用new出来
不要忘了对dao提供set。get方法,因为IOC的底层其实就是利用反射机制实现的,他把dao注入进来,其实底层就是通过反射set进来的。

4.下一步我们就是定义我们自己的ClassPathXmlApplicationContext类了,通过他,在我们new出他的对象的时候,他来加载配置文件,然后把我们的dao操作注入到我们的service层

在spring中,ClassPathXmlApplicationContext类实现了BeanFactory接口,在此我们也定义一个BeanFactory接口,其实这个接口没什么具体的作用,我们就是为了来模拟spring。
BeanFactory接口其实很简单,就定义了一个getBean方法,提供的bean的id,从bean容器内把对应的bean取出来。

public interface BeanFactory {  
public Object getBean(String id);  
}

5.在定义实现类之前,我们先来看一下我们所需的xml是怎么编写的,
下面我们就具体来看一下beans.xml的配置(它用来表示Bean对象与Bean对象之间的依赖关系):

<beans>  
<bean id="stuDao" class="com.bzu.dao.imp.StudentDaoImp" />  
<bean id="stuService" class="com.bzu.service.imp.StudentServiceImp" >  
<property name="stuDao" bean="stuDao"/>  
</bean>  
</beans> 

6.具体的实现类

public class ClassPathXmlApplicationContext implements BeanFactory{
 
private Map<String, Object> beans = new HashMap<String,Object>();
 
public ClassPathXmlApplicationContext() throws Exception,Exception {
SAXBuilder sb = new SAXBuilder();
 
Document doc = sb.build(this.getClass().getClassLoader()
.getResourceAsStream("beans.xml")); // 构造文档对象
Element root = doc.getRootElement(); // 获取根元素HD
List list = root.getChildren("bean");// 取名字为bean的所有元素
 
for (int i = 0; i < list.size(); i++) {
Element element = (Element) list.get(i);
String id = element.getAttributeValue("id");
String clazz = element.getAttributeValue("class");
Object o = Class.forName(clazz).newInstance();
System.out.print("bean id is " + id);
System.out.println(", clazz is " + clazz);
beans.put(id, o);
 
// 遍历property
for (Element propertyElement : (List<Element>) element
.getChildren("property")) {
String name = propertyElement.getAttributeValue("name");// userDAO
String bean = propertyElement.getAttributeValue("bean");// u
Object beanObject = beans.get(bean);// UserDAOImpl instance
 
// 构造setter方法
String methodName = "set" + name.substring(0,1).toUpperCase()
+ name.substring(1);
System.out.println("setter method name = " +methodName);
 
Method m = o.getClass().getMethod(methodName,
beanObject.getClass().getInterfaces()[0]);
m.invoke(o, beanObject);
}
}
}
 
@Override
public Object getBean(String id) {
return beans.get(id);
}
}

首先我们定义了一个容器Map<String, Object> beans,这个容器的作用就是用来装我们从配置文件里解析来的一个个bean,为什么要用map类型,我想大家也差不多能猜到吧,我们配置文件中每一个bean都有一个id来作为自己的唯一身份。我们把这个id存到map的key里面,然后value就装我们的具体bean对象

ClassPathXmlApplicationContext的构造方法,这个构造方法是我们spring管理容器的核心,这个构造方法的前半部分是利用的jdom解析方式,把xml里面的bean一个个的解析出来,然后把解析出来的bean在放到我们bean容器里。后半部分主要是在对配置文件进行解析出bean的同时去查看一下这个bean中有没有需要注射bean的,如果有的话,他就去通过这些里面的property属性获取他要注射的bean名字,然后构造出set方法,然后通过反射,调用注入bean的set方法,这样我们所需要的bean就被注入进来了。
7.测试spring到底能不能自动把我们所需要的dao层注入给service。


public static void main(String[] args) throws Exception {  
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();  
Student stu = new Student();  
StudentService service = (StudentService) context.getBean("stuService");  
service.add(stu);  
}  

参考文章https://blog.csdn.net/mlc1218559742/article/details/52774805

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容

  • 2.1 我们的理念是:让别人为你服务 IoC是随着近年来轻量级容器(Lightweight Container)的...
    好好学习Sun阅读 2,707评论 0 11
  • 这部分主要是开源Java EE框架方面的内容,包括Hibernate、MyBatis、Spring、Spring ...
    杂货铺老板阅读 1,362评论 0 2
  • 1.JVM 堆内存和非堆内存 堆和非堆内存按照官方的说法:“Java 虚拟机具有一个堆(Heap),堆是运行时数据...
    yanzhu728阅读 906评论 0 0
  • 本来是准备看一看Spring源码的。然后在知乎上看到来一个帖子,说有一群**自己连Spring官方文档都没有完全读...
    此鱼不得水阅读 6,928评论 4 21
  • 前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 单例模式你会几种写法? 工...
    Java3y阅读 2,283评论 1 60