换种眼光看Spring之bean是怎么诞生的(一)
Java的世界里处处存在了对象,有时候换一种眼光往往会给自己带来与之前大不一样的理解。
一个对象的出现离不开字节码,拿classforname来讲,classforname("...") 就像问你 狗 ,在你脑子里立马就出现了狗的样子,这就是狗的类,拉布拉多就出现拉布拉多狗的类,就类似于一个加载的过程,想要得到私有的方法,私有的类,比如拉布拉多和其他种类狗的区别,私有的用setAccessible设置为true,这样就可以调用,这其中加载的过程一眼就看到了父类也会加载进去,这就是类的初始化。
而这里还要说的是classloader是从BootStrapClassLoader开始,到ExtClassLoader再到AppClassLoader,再到自己的ClassLoader。很多人看到这些有的会很明白,同样的也有很多大头的,其实拿我们自身来说,我们要生存,首先我们自己得先活着,这就要求我们有血有肉,各个器官各种完好,BootStrapClassLoader不就是类似于干这事的么,它主要用于加载一些Java自带的核心类,是不能被替换掉的,由jvm内核实现,只有加载了这些最核心的内容,才会有后面classloader的存在机会。
在有了基本的器官之后,作为人,我们要生存还需要一些本能,呼吸,眨眼,条件反射(先天的),这个就类似于ExtClassLoader,其是加载在jre/lib/ext下的jar包,当然,我们也可以把自己的jar放到里面去,通过这个来加载,毕竟我们的好多先天的条件反射也是慢慢进化来的,是不是很形象
作为人,我们可以学习到很多技能,认识很多事物,每个人的所见都不一样,每个人都是一个独立的虚拟机,这里就谈到了AppClassLoader,它加载的是classpath下面的内容,默认情况都由其加载。
当然,凡事总有特殊,用户自定义的classloader要加载的内容不在上面的classpath范围内,怎么加载完全自己去定义,就像你从未见过某一种东西,你怎么去知道那是什么,要不就不打算认识说不知道,要不就给其编个名字安上!
上面说了一些class字节码的加载顺序,然后就是对其进行解析校验,最后是初始化,既然说到了这里,那就提下,初始化的时候会调用Class对象自身的构造函数,这里static块其实是个坑,当多个线程同时访问这个类时,必须等static块执行完,要不会发生阻塞,所以不适合编写大量的业务尤其是i/o逻辑业务
在classloader源码里发现了如下代码:
protected final Class<?> defineClass(String name, byte[] b, int off, int len)
throws ClassFormatError
{
return defineClass(name, b, off, len, null);
}
通过传入byte[]数组就可以动态的加载Class类,这就牵扯到了字节码加强。
终于和上一篇接着了,只要接触过Spring都知道,AOP,动态代理,追根究底都是字节码增强,所以也免不了俗,先说动态代理,看过很多这方面的文章,说说自己的理解,首先,jdk的动态代理,有点类似于专卖店,我拿房地产中介来说可能更好理解一些,一个共同的接口,卖房,房主实现了卖方的接口,房产中介也实现了卖方的接口,然后要有一套卖家卖房的处理流程也就是处理类handler,这个处理类的内部的invoke方法,如下图所示:
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
包含了代理对象,代理方法,方法参数对象,方法内部由被代理的对象来实现,其实就是包含了中介,卖房扯的过程,方法里面由卖家来实现
java.lang.reflect.Proxy下的newProxyInstance()方法如下所示
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
} /*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs); /*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
} final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
说白了就是想得到一个代理,就需要卖家的字节码,卖房的接口,和那个处理类handler,jdk动态代理的不好处也是显而易见的,必须实现接口,只能调用接口对应的方法,实例的其他方法无法访问,从这点也启示了我们面向接口编程和多态的用处。
暂时先敲这么多吧,剩下的下篇接着说
换种眼光看Spring之bean是怎么诞生的(一)的更多相关文章
- spring实例化bean三种方式
我看了这篇博文<https://www.cnblogs.com/zhanglei93/p/6221546.html>,以及自己实践总结了关于spring实例化bean对象的3种方式. 一. ...
- 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比
[原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...
- Spring中bean的四种注入方式
一.前言 最近在复习Spring的相关内容,这篇博客就来记录一下Spring为bean的属性注入值的四种方式.这篇博客主要讲解在xml文件中,如何为bean的属性注入值,最后也会简单提一下使用注解 ...
- 如果你每次面试前都要去背一篇Spring中Bean的生命周期,请看完这篇文章
前言 当你准备去复习Spring中Bean的生命周期的时候,这个时候你开始上网找资料,很大概率会看到下面这张图: 先不论这张图上是否全面,但是就说这张图吧,你是不是背了又忘,忘了又背? 究其原因在于, ...
- 面试阿里,字节,美团必看的Spring的Bean管理详解
IOC容器 工厂只负责创建对象,而Spring当然不仅仅是一个对象工厂,其核心是一个对象容器,其具备控制反转的能力,所以也称为IOC容器. 帮助我们存放对象,并且管理对象,包括:创建.销毁.装配,这样 ...
- Spring三 Bean的三种创建方式
创建Bean的三种方式在大多数情况下,Spring容器直接通过new关键字调用构造器来创建Bean实例,而class属性指定Bean实例的实现类,但这不是实例化Bean的唯一方法.实际上,Spring ...
- spring创建bean的三种方式
spring创建bean的三种方式: 1通过构造方法创建bean(最常用) 1.1 spring默认会通过无参构造方法来创建bean,如果xml文件是这样配置,则实体类中必须要有无参构造方法,无参构造 ...
- Spring获取bean的几种方式
工作中需要对一个原本加载属性文件的工具类修改成对数据库的操作当然,ado层已经写好,但是需要从Spring中获取bean,然而,工具类并没有交给Spring来管理,所以需要通过方法获取所需要的bean ...
- Spring实例化Bean三种方法:构造器、静态工厂、实例工厂
Spring中Bean相当于java中的类,可以通过xml文件对bean进行配置和管理. 一.Bean的实例化: 构造器实例化.静态工厂实例化.实例工厂方式实例化. 目录: 构造器实例化: xml配置 ...
随机推荐
- 全国省市级联数据sql语句 mysql版
全国省市级联数据sql语句 mysql版 --省级 provincial create table provincial ( provincialID int, provincialName ), p ...
- 关于最大流的EdmondsKarp算法详解
最近大三学生让我去讲课,我就恶补了最大流算法,笔者认为最重要的是让学弟学妹们入门,知道算法怎么来的?为什么是这样?理解的话提出自己的改进,然后再看看Dinic.SAP和ISAP算法….. 一.概念引入 ...
- tortoisesvn的安装与使用
1.下载安装文件,我用的是1.6.同时可以下载一个中文的安装包. 2.我在F盘建立了一个文件夹tortoisesvn,专门用来放置版本目录文件.然后右键这个文件夹,选择tortoisesvn-> ...
- 练习--LINUX进程间通信之无名管道PIPE
IBM上放的这个系统不错,刚好可以系统回温一下LINUX的系统知识. http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/ 感觉年纪大了,前几 ...
- hdu 4878 ZCC loves words AC自动机+中国剩余定理+快速幂
题意就不说了. 分析:折腾好几天自己写的代码还是看了别人代码后发现几乎没什么复杂度的差别,可是就是一直超时,后来干脆照着别人写啊,一直WA,就在准备放弃干脆先写这篇博客的时候,又看了一眼WA的代码,发 ...
- UVA 825 Walkiing on the safe side
根据地图,要求固定两点间最短路径的条数 . 这题的输入数据就是个坑,题目有没有说明数据之间有多个空格,结尾换行符之前也不止一个空格,WA了好几遍,以后这种情况看来都要默认按照多空格的情况处理了. 可以 ...
- 乱序双发射 和 GHB的分支预测
乱序执行(out-of-order execution)是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理的技术.比方Core乱序执行引擎说程序某一段有7 条指令,此时CPU ...
- 快速排序法QuickSort
/** * * @author Administrator * 功能:交换式排序之快速排序 */ package com.test1; import java.util.Calendar; publi ...
- 第六章Audio设备
6.1 Audio设备介绍 USB协议制定时,为了方便不同设备的开发商基于USB进行设计,定义了不同的设备类来支持不同类型的设备.虽然在USB标准中定义了USB_DEVICE_CLASS_AUDIO- ...
- LinuxShell_variable+if+while
[root@ossec-server mybash]# vim ./hello.sh #! /bin/sh # This is a example bash script echo "Hel ...