1.spring 体系结构:
spring的五个模块:IOC,AOP,数据访问和集成,Web及远程操作,测试框架;
IOC:BeanFactory接口是Spring框架的核心接口,实现类与类之间的依赖可以从代码中脱离出来,用配置文件的方式进行依赖关系的描述;
Context模块构建与核心模块之上,拓展了BeanFactory的功能,实现Bean生命周期控制,il8n国际化,框架事件体系,资源加载透明化等体系,另外还提供了许多企业级的服务,如邮件服务,任务调度,JNDI定位,EJB集成,远程访问等。ApplicationContext是Context模块的核心接口;
AOP:面向切面编程;
数据访问和集成:借助AOP技术,实现了数据库持久层框架的访问;在实际项目中的DAO层;可以通过jdbc,Hibernate,iBatis来实现;包括JDBC ORM OXM JMS ;
Web及远程操作:该模块建立在ApplicationContext模块之上,提供了Web应用的各种工具类;可以整合Structs、WebWork等WEB框架;当然,spring也提供了自己的框架SpringMVC
测试框架:
2.IOC:
JAVA反射机制:
@Override
public Car initByDefaultConst() {
//1通过类装载器加载Car对象
ClassLoader loader=Thread.currentThread().getContextClassLoader();
Car car=null;
try {
//2.获取类的默认构造器对象并通过它实例化Car
Class clazz=loader.loadClass("beans.Car");
Constructor cons=clazz.getDeclaredConstructor((Class[])null);
car=(Car)cons.newInstance();
//3.通过反射方法设置属性
Method setBrand=clazz.getMethod("setBrand", String.class);
setBrand.invoke(car, "兰博基尼");
Method setColor=clazz.getMethod("setColor", String.class);
setColor.invoke(car, "red");
Method setMaxSpeed=clazz.getMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car, 200);
Method setAll=clazz.getMethod("setAll", String.class,String.class);
setAll.invoke(car, "迈巴赫","棕绿色");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return car;
}
类加载器ClassLoader:
类加载器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件;在java中,类装载器把一个类装入JVM中,要经过以下步骤:
1.装载:查找和导入Class文件;
2.链接:执行校验、准备和解析步骤,其中解析步骤是可以选择的:
a)校验:检查载入Class文件数据的正确性;
b)准备:给类的静态变量分配空间;
c)解析:将符号引用转成直接引用;
3.初始化:对类的静态变量、静态代码执行初始化工作;
类装载工作由ClassLoader及其子类负责;JVM运行时会产生3个ClassLoader:AppClassLoader(系统类装载器)、ExtClassLoader(扩展类装载器)、根装载器;这三个依次继承;但在JAVA中,根装载器由C++编写,故看不到;在java中所有的类装载都是由这三个类装载器协作共同完成的;
那么这三个类又是如何分工的呢?
根装载器负责JRE的核心类库,eg:JRE目录下的rt.jar、charsets.jar等;
扩展类装载器(ExtClassLoader)负责装载JRE扩展目录ext中的JAR类包;
系统类装载器(AppClassLoader)负责装载Classpath路径下的类包;
现在我们来假设,有一个用户自己写了一个恶意的java基础类(如java.lang.String),那么这个类一旦被加载到JVM后,其后果不堪设想;那么JVM又是怎么去处理的呢?
JVM在装载类时,有一个默认机制:全盘负责委托机制;全盘负责是指一个类加载器加载一个类时,该类的依赖及引用的类也全部由该加载器加载;所以,一个class在JVM中有且仅有一个ClassLoader;委托机制是指我们在加载一个类时,先委托父装载器寻找目标类,如果找不到。在从自己的类路径中查找;这样,即使恶意的类,但不会被加载;因为加载java.lang.String时,先由根类装载器扫描其对应路径是否有目标类,如果有,则加载;没有再委托给其子类扫描;所以,即使恶意的类,永远还没被扫描到,就已经使用系统加载的类加载完毕;
关于错误信息java.lang.NoSuchMethodError的错误信息:通常是由于多个版本的类包,在进行加载时,没有加载到对应版本;
4.ClassLoader重要方法:(ClassLoader是一个抽象类,位于java.lang中);
Class loadClass(String name); 加载指定类;name参数是需要装载的类的全限定类名;该方法有一个重载loadClass(String name, boolean resolve); resolve告诉装载器是否要解析该类;
Class defineClass(String name,byte[] b,int off,int len);将类文件的字节数组转换为JVM内部的java.lang.Class对象;字节数组可以从本地文件系统、远程网络获取;
Class findSystemClass(String name); 从本地文件载入Class文件;JVM默认的装载机制;
Class findLoadedClass(String name);查看classLoader是否已装入某个类;如果已装入,则返回java.lang.Class对象,否则,返回null;如果强行装载已存在的类,则会抛出链接错误;
ClassLoader getParent();获取弗雷==类装载器的父类装载器;
5.Java反射机制:(可以从Class对象中获取构造参数、成员变量、方法类元素的反射对象,并以编程的方式通过这些反射对象对目标对象;这些反射类在java.reflect包中定义);
Constructor:类的构造函数反射类;通过getConstructors()方法获得所有构造函数反射对象数组。并且可以通过newInstance();获得实例;
Method:类方法的反射类,通过getDeclareMethods()方法获取类的所有方法反射类对象数组;并通过invoke调用;
Field:类的成员变量的反射类,通过getDeclaredFields()方法获取类的成员变量反射对象数组;
在访问private、protected成员变量和方法时必须通过setAccessible(boolean access)方法取消java语言检查,否则将抛出IllegalAccessException;